Scroll-snapping breaks jQuery animated scroll

Viewed 153

I have a scroll view with mandatory scroll-snapping:

scroll-snap-type: y mandatory;

I also have some buttons which provide shortcuts to the different elements of the scroll view. When a button is clicked, I use jQuery to animate the selected element into view:

$('#scroller').animate({ scrollTop:$('#scroller').scrollTop() + $(element).offset().top -$('#scroller').offset().top }, { duration: 'slow', easing: 'swing'});

This works perfectly in Safari. In Chrome and Firefox (Mac), however, it seems scroll-snapping breaks jQuery's animate function. Instead of a smooth scrolling, the element just awkwardly jerks into view. If I remove the scroll-snapping it works as expected.

I tried to be clever and disable the scroll-snapping whenever a button is clicked, then enable it again on manual mouse wheel scrolling:

$('#scroller').on('wheel', function(e) {
  $('#scroller').css('scroll-snap-type', 'y mandatory');
});

This way, I got it to work both in Safari and Firefox. But Chrome still won't play ball. The trick kind of works, but, oddly enough, once or twice only. After clicking a button, it seems it simply ignores to enable the scroll-snapping again.

Any idea how to fix this? Thanks!

Demo: https://codepen.io/gurgel/pen/yLLORar

EDIT: After reading this post I got it working on all browsers using this smoothscroll polyfill. I would still prefer a vanilla solution though – it seems so close.

EDIT 2: Added snippet per suggestion:

$(document).ready(function() {
    
   $('#scroller').on('wheel', function(e) {
     /* This gets the scroll-snapping working again in Firefox, but not in Chrome */
  $('#scroller').css('scroll-snap-type', 'y mandatory');
  });               
  
  
});
  
  
function changeView(index) {
  
  /* Workaround to enable smooth scrolling in Chrome and Firefox  */
  $('#scroller').css('scroll-snap-type', 'none');
  
  var id = 'view ' + index;
  var element = document.getElementById(id);
 $('#scroller').animate({ scrollTop:      $('#scroller').scrollTop() + $(element).offset().top -$('#scroller').offset().top }, { duration: 'slow', easing: 'swing'});
}
#wrapper {
  height:100vh;
  width:50vw;
  overflow: hidden;
  display: flex;
  flex-direction:row;
}
#menu ul {
  list-style:none;
  padding:0 20px 0 0;
  cursor: pointer;
  width:60px;
}
#menu ul li {
  border:1px solid green;
}

#scroller {
  flex-grow:1;
  overflow-y: scroll;
  scroll-snap-type: y mandatory;
  /* 
  This breaks the animated scrolling in Chrome/FF.
  */
}
.view {
  padding:10px;
  scroll-snap-align: start;
}




/* Irrelevant styling */
.view:nth-child(1) {
  background:#b3de81;
}
.view:nth-child(2) {
  background:#6eb5c0;
}
.view:nth-child(3) {
  background:#E94353;
}
.view:nth-child(4) {
  background:#faaf08;
}
.view:nth-child(5) {
  background:#CFA4DB;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="wrapper">
  
  <div id="menu">
   <ul>
     <li onclick="changeView(1)">1</li>
    <li onclick="changeView(2)">2</li>
    <li onclick="changeView(3)">3</li>
    <li onclick="changeView(4)">4</li>
    <li onclick="changeView(5)">5</li>
    </ul>
  </div>
  
  <div id="scroller">
    <div id="view 1" class="view">
     <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
    </div>
    <div id="view 2" class="view">
     <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
    </div>
    <div id="view 3" class="view">
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
    </div>
    <div id="view 4" class="view">
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
    </div>
    <div id="view 5" class="view">
     <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
    </div>
  </div>
</div>

0 Answers
Related