javascript - 滚动事件持续多长时间?

标签 javascript jquery html css

我遇到一个由滚动事件引起的问题,这个问题可以重现如下:

  1. 将焦点设置到默认情况下在浏览器窗口中看不到的元素(需要滚动才能看到它)。

  2. 然后附加一个监听器以捕获滚动事件。

令我困惑的是,当我将焦点设置在未看到的元素上时,它会触发滚动事件,监听器如何捕获稍后附加的滚动事件?我想滚动事件可能会持续一段时间,但会持续多久呢?谁能给我一个建议?

这里有一个简单的代码来重现它:

<html>
<head>
<script type="text/javascript">
   var onchange = function(){
       var ip1 = document.getElementById("target");
       var ip2 = document.getElementById("source");
       var parent = document.getElementById("parent");
       ip2.focus();
       document.onscroll = function(e){
          console.log("scroll");
       };
   }
</script>
</head>
<body onload="onchange()">
<input id="target"></input>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<div id="parent">
 <input id="source">
</div>

最佳答案

对此的解释是 JavaScript 事件处理程序不会立即触发。因此,当您调用 focus() 时,它不会立即将焦点放在第二个文本框上。相反,它会执行 onchange 函数的其余部分,然后滚动页面。当页面滚动时,scroll 事件的事件处理程序已经设置完毕。

原因如下:当事件在 JavaScript 中发生时,它被放置在消息队列(JavaScript 运行时引擎的内部组件)中。消息从该队列中删除,并在事件循环的每个“回合”中进行处理。事件循环轮次之间的时间量各不相同,但通常每轮不超过 4 毫秒。

要解决您的问题,您可以在下一轮事件循环中设置绑定(bind)(在 scroll 事件触发后)。为此,开发人员通常会执行以下操作:

setTimeout(function () {
    document.onscroll = function (e) {
        console.log("scroll");
    };
}, 0);

即使我指定了 0 毫秒的延迟,setTimeout 回调也不会触发,直到事件循环的下一轮,所以它真的发生在大约 4 毫秒之后。您可以保证在处理完 focus 事件之前不会设置绑定(bind)(focus 消息总是在 setTimeout 之前添加到消息队列中) 消息加入到消息队列中,队列中的消息按顺序处理。

有人提议在 JavaScript 中引入一个 setImmediate 函数,目的是让开发人员可以在事件循环的下一轮执行代码,但全局采用该函数似乎不太可能。请参阅:https://developer.mozilla.org/en-US/docs/Web/API/Window.setImmediate

该函数的工作方式与上面的 hack 类似:

setImmediate(function () {
    document.onscroll = function (e) {
        console.log("scroll");
    };
});

如果您感兴趣,有一些用于 setImmediate 的 polyfill,它们比 setTimeout hack 更快,并且使用 HTML 5 postMessage应用程序接口(interface)。请参阅:https://github.com/YuzuJS/setImmediate

这是与损坏代码一起运行的修复代码的 JSBin:http://jsbin.com/laculukaqidu/1/edit?js,console,output

关于javascript - 滚动事件持续多长时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25614788/

相关文章:

jquery - 防止默认值在我的 javascript 中不起作用

html - 避免在网页上加载图像时回流/闪烁的方法?

html - 如何使用 HTML/CSS 在网页中添加斜线?

javascript - 如何创建一个 if 语句来检查值变量是否全部非空?

javascript - 自动计算多个下拉选择

javascript - 正则表达式匹配引号之外的字符串,如果引号不完整,则不匹配任何内容

jQuery ("#myCarousel").jcarousel 不是一个函数吗?

javascript - css3动画中的虚线边框动画

javascript - 如何检查悬停函数中的 2 个条件

javascript - moment.js 中的 isValid() 和 _isValid 有什么区别?