滚动事件持续多长时间?

时间:2014-09-02 01:52:17

标签: javascript jquery html css

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

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

  2. 然后附加一个侦听器来捕捉滚动事件。

  3. 我感到困惑的是,当我将焦点放在未看到的元素上时,它会触发一个滚动事件,听众如何能够捕获后来附加的滚动事件?我想也许滚动事件会持续一段时间,但多久?任何人都可以给我一个建议吗?

    这是一个重现它的简单代码:

    <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>
    

1 个答案:

答案 0 :(得分:0)

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

这就是为什么:当一个事件发生在JavaScript中时,它被放置在一个消息队列(JavaScript运行时引擎的内部组件)上。消息将从该队列中删除,并在每个&#34;转动&#34;事件循环事件循环转动之间的时间量会有所不同,但通常每转一圈不会超过4毫秒。

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

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

即使我指定了0 ms的延迟,setTimeout回调也不会触发,直到事件循环的下一个转弯,所以它确实在大约4 ms后发生。您可以保证在处理focus事件之后不会设置绑定(在添加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有一些比setTimeout黑客更快的填充,并使用HTML 5 postMessage API。请参阅:https://github.com/YuzuJS/setImmediate

这里是与破坏的代码一起运行的固定代码的JSBin:http://jsbin.com/laculukaqidu/1/edit?js,console,output