2014-09-02 76 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