Matheus Teixeira
Matheus Teixeira

Reputation: 31

carousel, let horizontal scrolling end movement when parent element vertical scrolling is moved

I created a carousel similar to the one on Instagram that is working, but I realized that if I move the scroll y of the parent element before the scroll x movement of the child element ends it will not end.

gif of the example below ...

note: sorry for bad English, not my native language.

code

.container {
  width: 100%;
  display: flex;
  flex-direction: column;
  overflow-y: scroll;
  .x {
    margin-top: 30px;
    display: flex;
    overflow-x: scroll;
    scroll-snap-type: x mandatory;
    div {
      flex: 0 0 auto;
      scroll-snap-align: start;
      width: 100vw;
      height: 100vw;
    }
    .x-item1 {
      background: green;
    }
    .x-item2 {
      background: blue;
    }
  }
}
<Container>
  <div className="x">
    <div className="x-item1" />
    <div className="x-item2" />
  </div>

  ... other divs
</Container>

--->> Example Gif !! <<---

Upvotes: 2

Views: 579

Answers (2)

Matheus Teixeira
Matheus Teixeira

Reputation: 31

I found a solution that, in my opinion, meets my proposal without losing the performance of the functionality ...

I just thought that there could be a delay in scrollIntoView, like "behavior: smooth" ...

https://developer.mozilla.org/pt-BR/docs/Web/API/Element/scrollIntoView

but it didn't work if someone wants to add an improvement, thanks.

in the container I put an "onTouchStart"

<Container className="works" onTouchStart={() => handleCarousel()} >
  <div className="x">
    <div className="x-item1" />
    <div className="x-item2" />
  </div>

  ... other divs
</Container>

function handleCarousel...

const handleCarousel = () => {
    const works = Array.from(document.querySelectorAll('.work-content'));
    const carousels = Array.from(document.querySelectorAll('.work-carousel'));
    carousels.forEach(carousel => {
      if (carousel.scrollLeft % window.innerWidth !== 0) {
        const item = document.querySelector(
          `.work-content:nth-child(${
            works.indexOf(carousel.parentElement) + 1
          }) > div.work-carousel > img.work-carousel-item-active`, 
        ); // in another function I already control which image is being viewed and add this class
        const scroll = document.querySelector('.works').scrollTop; // optional: get vertical scroll value
        item.scrollIntoView(); // horizontal scrolling gains focus
        document.querySelector('.works').scrollTop = scroll; // optional: returns vertical scroll value
      }
    });
  };

Upvotes: 1

Aaron
Aaron

Reputation: 2227

I believe this is the expected behavior; scrolling in one direction interrupts scrolling in the other, even scrolling that's declared manditory by Scroll Snap CSS attributes.

If you dislike this behavior, you might use a JS-based animation that programmatically scrolls the container horizontally, since this won't be affected by vertical scrolling.

Sorry I can't help more.

Upvotes: 0

Related Questions