Home > front end >  How to stop scrollIntoView() from scrolling container to top of page?
How to stop scrollIntoView() from scrolling container to top of page?

Time:12-22

I'm trying to build a simple, "mostly-css" image carousel that uses scroll-snap, but also has navigation buttons to control which slide is currently in view. The only solution I've found is to use scrollIntoView() on the target element, which does what I want but it also always scrolls the target element to the top of the page. I want the target carousel slide and container to stay where they are, and I just want the slide to scroll horizontally into view. I'm looking at an example by Adam Argyle where he does just this, and the container stays where it is, and I can't what's different about his demo.

I made a codepen to demonstrate.

https://codepen.io/krjo-the-decoder/pen/dyjPrLy

Clicking the numbered buttons on the bottom will correctly scroll to the right slide, but also scrolls the whole container up the page.

I've tried using scrollTo() just before and just after scrollIntoView() to set the y axis scroll of the container to it's existing position, and that had no effect.

<!-- Using tailwind.css -->
<div >
  <h1 >Scroll-snap Carousel</h1>
  <div >
    <img src="https://via.placeholder.com/500" width="500" height="500"  data-slide>
    <img src="https://via.placeholder.com/500" width="500" height="500"  data-slide>
    <img src="https://via.placeholder.com/500" width="500" height="500"  data-slide>
    <img src="https://via.placeholder.com/500" width="500" height="500"  data-slide>
  </div>
  <nav >
    <button  type="button" data-index="0">1</button>
    <button  type="button" data-index="1">2</button>
    <button  type="button" data-index="2">3</button>
    <button  type="button" data-index="3">4</button>
  </nav>
</div>

<script>
const slides = document.querySelectorAll('[data-slide]');
document.querySelectorAll('button').forEach(button => {
  button.addEventListener('click', event => {
    console.log('event',event);
    slides[event.target.dataset.index].scrollIntoView({
      behavior: 'smooth',
      inline:   'center',
    });
  });
});
</script>

CodePudding user response:

Try adding block: 'nearest' to your scrollIntoView options, like this:

document.querySelectorAll('button').forEach(button => {
  button.addEventListener('click', event => {
    console.log('event',event);
    slides[event.target.dataset.index].scrollIntoView({
      behavior: 'smooth',
      inline:   'center',
      block:    'nearest',
    });
  });
});
  • Related