首页 > 解决方案 > jquery 捕获在 .on() 之前触发的事件

问题描述

DIV.scrollTop(200)只在 bind 之后调用函数DIV.on('scroll'),但DIV.on('scroll')捕获DIV.scrollTop(200)在 bind 之前调用的事件!

为什么以及如何避免这种情况?

<div id="1" style="width:300px; height:300px; overflow:scroll; border:1px solid;">
     <div style="width:600px; height:600px; "></div>
</div>


$('#1').scrollTop(200);

$('#1').on('scroll', function(){
  $(this).css("background-color", "red");
});

jsfiddle 示例

标签: jqueryevents

解决方案


scroll事件看起来是异步的,甚至强制立即重绘似乎也不起作用。使用 vanilla JS 而不是 jQuery 也不会改变观察到的行为。

我看不到任何以编程方式确定scroll事件是由用户触发还是由脚本触发的方法。我认为添加延迟是您唯一的解决方法。

重绘(将触发scroll事件)将在完成后发生,因此仅requestAnimationFrame以下情况下附加侦听器:

  • requestAnimationFrame运行(表明将很快发生重绘),并且

  • a 之后setTimeout(表示已发生重绘)

$('#1').scrollTop(200);

requestAnimationFrame(() => {
  setTimeout(() => {
    $('#1').on('scroll', function() {
      $(this).css("background-color", "red");
    });
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="1" style="width:300px; height:300px; overflow:scroll; border:1px solid;">

  <div style="width:600px; height:600px; "></div>

</div>

跨浏览器工作,重新绘制时间的机制由规范保证。

另一种可能性是添加另一个scroll运行一次的处理程序,并停止事件的传播,以便下一个处理程序看不到它:

$('#1').scrollTop(200);

$('#1').one('scroll', function(event) {
  event.stopImmediatePropagation();
});

$('#1').on('scroll', function() {
  $(this).css("background-color", "red");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="1" style="width:300px; height:300px; overflow:scroll; border:1px solid;">

  <div style="width:600px; height:600px; "></div>

</div>


推荐阅读