jquerycss-transitionscarouselhorizontal-scrolling

Scroll to target horizontally with jQuery


Trying to revolutionize the world of carousels by creating something super simple and semantic that simply works with anchor links. It works mostly, but it jumps to the href rather than scrolling smoothly. What am I doing wrong here?

Edit: can't figure out how to include jQuery here, so here's a pen:

https://codepen.io/tactics/pen/xxNvYzV

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.js" integrity="sha512-+k1pnlgt4F1H8L7t3z95o3/KO+o78INEcXTbnoJQ/F2VqDVhWoaiVml/OEHv9HsVgxUaVW+IbiZPUJQfF/YxZw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
$(document).ready(function() {
  $("nav a").click(function() {
    var $carousel = $('.carousel');
    var scrollTo = $(this).attr('href');
    // change its bg
    .css('background', '#9f3')
      // retrieve its position relative to its parent
      .position().left;
    console.log(scrollTo);
    // simply update the scroll of the carousel
    // $('.carousel').scrollLeft(scrollTo); 
    // use an animation to scroll to the destination
    $carousel
      .animate({
        'scrollLeft': scrollTo
      }, 500);
  });
});
</script>
.carousel {
  width: 300px;
  height: 100px;
  overflow-x: auto;
  overflow-y: hidden;
}

.frame {
  position: relative;
  height: 100px;
  width: 770px;
}

.frame div {
  height: 90px;
  width: 60px;
  float: left;
  margin: 5px;
  background: #39f;
}
<div class="carousel">
  <div class="frame">
    <div id="d1"></div>
    <div id="d2"></div>
    <div id="d3"></div>
    <div id="d4"></div>
    <div id="d5"></div>
    <div id="d6"></div>
    <div id="d7"></div>
  </div>
</div>
<nav>
  <p><a href="#d1">1</a></p>
  <p><a href="#d6">6</a></p>
</nav>


Solution

  • You can add the scroll-behavior attribute in your CSS

    .carousel {
      width: 300px;
      height: 100px;
      overflow-x: auto;
      overflow-y: hidden;
      scroll-behavior: smooth;
    }
    
    

    or using jquery:

    $(document).ready(function() {
      $("nav a").click(function() {
        var $carousel = $('.carousel');
        
        // selecting the target element to scroll to
        var target = $($(this).attr('href'));
        
        // calculating the proper offset to scroll to
        var scrollTo = target.offset().left - $carousel.offset().left + $carousel.scrollLeft();
        
        // setting css
        target.css('background', '#9f3');
    
        $carousel
          .animate({
            'scrollLeft': scrollTo
          }, 500);
      });
    });