Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent scroll event from firing after adjusting `scrollTop` when mouse pulls up scrollbar?

I’m trying to push the scrollbar down a few px when the user scrolls to the top of the <div>. The problem is that after the scroll is pushed down a few px (after I scroll to the top) the browser still thinks that my mouse is at the top of the <div> when my mouse is still held down (mousedown). This is bad as the event keeps firing.

Features I am trying to achieve:

  1. Scroll to the top of the <div>
  2. Scroll gets pushed down a few pixels but the function does not fire again even if my mouse is still on mouse down.

I think it may be the way I detect the function through onscroll. Please test my code and see the console.log() if I am not making sense.

var wrapper = document.getElementById('scroll-box');
wrapper.onscroll = function (evt){
  //detect when scroll has reached the top of the frame
  if(wrapper.scrollTop === 0){
      console.log('top of frame');
      wrapper.scrollTop += 500;
  }

  //detect when scroll has reached the bottom of the frame
  if(wrapper.scrollHeight - wrapper.scrollTop === wrapper.clientHeight){
    console.log('bottom of frame');
  }
}

wrapper.scrollTop += 3000;
.scroll-box {
  width: 400px;
  height: 300px;
  background-color: gray;
  overflow-y: scroll;
}
  
div ul li {
  padding: 50px;
}
<div class="scroll-box" id="scroll-box">
  <ul>
    <li>messages</li>
    <li>messages</li>
    <li>messages</li>
    <li>messages</li>
    <li>messages</li>
    <li>messages</li>
    <li>messages</li>
    <li>messages</li>
    <li>messages</li>
  </ul>
</div>
like image 867
jdogdvr Avatar asked Nov 21 '15 06:11

jdogdvr


1 Answers

As mentioned in the comments, the fact that the event will keep on firing and logging that the div is at the top is a natural result from it being pushed down and then dragged up again rapidly because the scrollbar hasn't been released. As far as I can see, there's no direct way to cancel that interaction.

But without creating a custom scrollbar this is probably the quickest fix, even if it is a minor hack :

Demo

var wrapper = document.getElementById('scroll-box'),
size = wrapper.clientWidth;

wrapper.addEventListener('scroll', function() {

  if (!wrapper.scrollTop) {
    console.log('top of frame');
    wrapper.scrollTop += 500;
    wrapper.setAttribute('style', 'width: ' + size + 'px; overflow: hidden');
    setTimeout(function() {
      wrapper.removeAttribute('style');
    }, 0);
  }
});

wrapper.scrollTop += 200;

Eliminating the scroll event by hiding overflow for the shortest possible amount of time. And setting clientWidth of the element as well to make it keep it's original width so the action is less noticeble.

like image 90
Shikkediel Avatar answered Oct 12 '22 22:10

Shikkediel