2011-06-30 44 views
4

我曾经假设我可以简单地将onhashchange事件处理程序设置为null,更改散列,然后将onhashchange事件处理程序设置为某些内容,但请考虑以下代码:暂时禁用JS事件并学习JS事件处理如何工作

window.onhashchange = null; 
window.location.hash = "this_should_not_concern_you"; 
window.onhashchange = function() {alert('chunky bacon')}; 
doOtherStuff(); 

因此,当has被改变时,没有事件处理程序用于散列更改,但我仍然收到“矮胖培根”的警报。


更新 我选择去与杰德的setInterval的解决方案。尽管它很有用(谢谢Jed),但它很丑,很脆弱。如果有一个(有点矛盾的onAllEventsHandled事件,那么我可以把我的onhashchange订阅在那里,并确保我不会意外地警告“矮胖培根”,因为doOtherStuff()需要2秒钟才能完成。

+1

+1对于矮胖培根..只是说在 –

回答

2

它是异步运行的。试试这个:

window.onhashchange = null; 
window.location.hash = "this_should_not_concern_you"; 
setTimeout(function() { window.onhashchange = function() {alert('chunky bacon')};}, 500); 

500ms的延迟给了它足够的时间来设置哈希值被改变后的处理程序。 (即使是0ms也可能足够堆栈事件)

+0

wooooWE是一个丑陋的解决方案! ...但它的工作原理! – JnBrymn

+0

我不能不同意。 :-) – glortho

+0

在0ms的事情上的好点。起初我没有注意到。 – JnBrymn

2

你的代码是一个事件循环的所有部分,因此,当事件触发下一个循环时,您的处理程序就位。事件循环的一个简单的例子是:

  1. 处理事件
  2. 清除调用栈
  3. 等待事件(回到步骤之一)

当你改变哈希在同事件循环,因为您正在分配回调,直到下一个事件循环才会处理它,而事件循环已经在那里等待事件。

window.location.hash = 'test1'; 

window.onhashchange = function() { 
    console.log(window.location.hash); 
}; 

window.location.hash = 'test2'; 

此代码将记录#test2两次。处理程序触发两次,但处理程序触发后的值是test2,两次都是。

+0

和解决这个问题的想法? – JnBrymn

+0

您需要在事件触发后处理它,Jed的设置超时的想法将其推入下一个事件循环才有效。 – Robert

0
window.onhashchange = null; 

window.location.hash = "this_should_not_concern_you"; 

window.onhashchange = function() { 
    window.onhashchange = function() {alert('chunky bacon')}; 
}; 

window.location.hash = "this_should";