滚动事件持续多长时间
how much time does a scroll event last?
我遇到了一个由滚动事件引起的问题,这个问题可以重现如下:
-
将焦点设置为默认情况下在浏览器窗口中看不到的元素(需要滚动才能看到)。
-
然后附加一个监听器来捕获滚动事件。
我困惑的是,当我将焦点设置在未看到的元素上时,它会触发滚动事件,侦听器如何捕捉稍后附加的滚动事件?我想滚动事件可能会持续一段时间,但会持续多久?有人能给我一个建议吗?
这里有一个简单的代码来复制它:
<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运行时引擎的内部组件)中。消息将从该队列中删除,并在事件循环的每个"回合"中进行处理。事件循环匝之间的时间量各不相同,但通常每匝不超过4ms。
为了解决您的问题,您可以在事件循环的下一轮中设置绑定(在scroll
事件触发之后)。为了做到这一点,开发人员通常会做一些类似的事情:
setTimeout(function () {
document.onscroll = function (e) {
console.log("scroll");
};
}, 0);
尽管我指定了0毫秒的延迟,但setTimeout
回调直到事件循环的下一轮才会启动,所以它确实发生在大约4毫秒之后。您可以保证在处理完focus
事件之后才会设置绑定(focus
消息总是在setTimeout
消息添加到消息队列之前添加到消息排队中,并且队列中的消息按顺序处理)。
有人提议在JavaScript中引入setImmediate
函数,以便开发人员在下一轮事件循环中执行代码,但似乎不太可能在全球范围内采用该函数。请参阅:https://developer.mozilla.org/en-US/docs/Web/API/Window.setImmediate
该功能将类似于上面的破解:
setImmediate(function () {
document.onscroll = function (e) {
console.log("scroll");
};
});
如果您感兴趣,setImmediate
的一些polyfill比setTimeout
破解更快,并且使用HTML5postMessage
API。请参阅:https://github.com/YuzuJS/setImmediate
下面是一个固定代码的JSBin,它与损坏的代码一起运行:http://jsbin.com/laculukaqidu/1/edit?js,控制台,输出
- 为什么我的上下文选择器和.buttonset()在ie中花费了这么长时间
- 谷歌地图需要很长时间才能在ie11中渲染
- 有没有一种方法可以检查javascript以毫秒为单位执行一个函数需要多长时间
- 我一直收到的控制台警告是什么?推迟长时间运行的计时器任务以提高滚动的流畅性
- 为什么这个代码不起作用?我花了很长时间试图弄清楚这一点
- 如何在长时间执行JavaScript期间显示微调器
- 长时间轮询:每个浏览器中的通知
- 完整日历:如何支持一次点击和不长时间点击
- 如何使用 javascript 停止对 asp.net 进行正在进行的回发(长时间运行的执行)
- 优化长时间点击事件
- 滚动事件持续多长时间
- 如何在长时间运行的事件中更新页面元素
- 钛合金事件监听器,同时长时间操作
- 需要很长时间才能完成的事件是否会改变“可变变量”的值?
- . window事件监听器持续多长时间?
- node.js事件循环如何记住它需要在长时间运行的操作完成后回调?
- JavaScript内部:事件循环每隔多长时间运行一次?
- 服务器发送的事件轮询导致长时间延迟
- 快速点击事件和长时间的鼠标按下事件的区别
- 套接字.IO需要很长时间才能触发断开连接事件