2014-09-02 77 views
1

我遇见引起滚动事件的问题,这个问题是可以重现如下:滚动事件持续多长时间?

  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> 

+0

不知道到底是什么问题,你是想在这里解决 - 和而滚动事件实际上并没有“最后“比任何其他事件都长,在滚动网站的过程中可能会经常触发它,如果您正在尝试根据该事件做某些事情,可能会产生性能影响。使用计时器的更深入的解释和可能的解决方法可以在这里找到:http://ejohn.org/blog/learning-from-twitter/ – CBroe 2014-09-02 02:05:40

回答

0

对此的解释是,JavaScript事件处理程序不会立即解雇。因此,当您拨打focus()时,它不会立即关注第二个文本框。相反,它执行onchange函数的其余部分,然后滚动该页面。在页面滚动时,scroll事件的事件处理程序已经建立。这是为什么:当JavaScript发生事件时,它被放置在消息队列(JavaScript运行时引擎的内部组件)上。消息从该队列中移除,并用事件循环的每个“转向”进行处理。事件循环之间的时间间隔不同,但通常每个循环不超过4毫秒。

为了解决您的问题,您可以在事件循环的下一个回合中设置绑定(在scroll事件触发后)。要做到这一点,开发人员通常这样做:

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

即使我指定的0毫秒的延迟,该setTimeout回调将不会触发,直到事件循环的下一个回合,所以后约4真的发生女士。确保在处理focus事件之后才会设置绑定(在将setTimeout消息添加到消息队列之前,focus消息始终添加到消息队列中,并且队列中的消息在订购)。

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

功能会的工作方式类似于上面的黑客:

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

如果你有兴趣,也有setImmediate那些比setTimeout破解速度更快,使用HTML几个polyfills 5 postMessage API。请参阅:https://github.com/YuzuJS/setImmediate

这里是沿着断码的运行固定码的JSBin:http://jsbin.com/laculukaqidu/1/edit?js,console,output