【问题标题】:How to prevent scroll event from firing after adjusting `scrollTop` when mouse pulls up scrollbar?当鼠标拉起滚动条时,如何防止在调整“scrollTop”后触发滚动事件?
【发布时间】:2016-02-23 18:04:27
【问题描述】:

当用户滚动到<div> 的顶部时,我正在尝试将滚动条向下推几像素。问题是,当我的鼠标仍然被按住时(mousedown),在滚动向下几个 px 之后(在我滚动到顶部之后),浏览器仍然认为我的鼠标位于 <div> 的顶部。这很糟糕,因为事件不断触发。

我想要实现的功能:

  1. 滚动到<div> 的顶部
  2. 滚动被向下推了几个像素,但即使我的鼠标仍在鼠标按下,该功能也不会再次触发。

我认为这可能是我通过onscroll 检测功能的方式。请测试我的代码,如果我没有意义,请查看console.log()

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>

【问题讨论】:

  • 你想做什么..?您的代码运行良好并在控制台中显示值。
  • 如果您按住鼠标并将其拖动到 div 的顶部,滚动会按预期被向下推,但浏览器仍然认为滚动在鼠标向下时位于 div 的顶部。您可以通过 console.log('top of frame') 看到它。例如滚动到顶部并将鼠标稍微移动到顶部或底部,控制台就会被填满 console.log('top of frame');即使卷轴已经被按下。
  • 您可以检查鼠标是否在滚动条以外的任何地方;如果它在滚动条和鼠标按下之外的其他东西上,是否阻止默认滚动事件?这有意义吗?
  • 即判断滚动条是否被点击了一个元素。

标签: javascript html scroll scrollbar


【解决方案1】:

正如 cmets 中所提到的,事件将继续触发并记录 div 位于顶部的事实是由于滚动条尚未释放而被向下推然后再次快速向上拖动的自然结果.据我所知,没有直接的方法可以取消该交互。

但如果不创建自定义滚动条,这可能是最快的修复方法,即使它是一个小技巧:

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;

通过在尽可能短的时间内隐藏溢出来消除滚动事件。并设置元素的clientWidth 以使其保持原来的宽度,从而使动作不那么明显。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-14
    • 2013-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多