暂时禁用JS事件&学习JS事件处理的工作原理

时间:2011-06-30 14:28:07

标签: javascript javascript-events

我原以为我可以简单地将onhashchange事件处理程序设置为null,更改哈希值,然后将onhashchange事件处理程序设置为某些内容,但请考虑以下代码:

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

所以当更改has时,没有用于哈希更改的事件处理程序,但我仍然收到“chunky bacon”的警报。


更新 我选择使用Jed的setInterval解决方案。虽然它有效(谢谢杰德),但它很丑陋而且很脆弱。如果有一个(有点自相矛盾的onAllEventsHandled事件,那么我可以将我的onhashchange订阅放在那里,并确保我不会因为{{1而意外警告“chunky bacon”需要2秒才能完成。

3 个答案:

答案 0 :(得分:2)

它以异步方式运行。试试这个:

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

500ms延迟使其有足够的时间在更改散列后设置处理程序。 (但是,即使是0ms也可能足以叠加事件。)

答案 1 :(得分:2)

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

  1. 处理事件
  2. 清除调用堆栈
  3. 等待事件(回到第一步)
  4. 当您在分配回调时更改同一事件循环中的哈希值时,直到下一个事件循环(已经有它在那里等待事件)时才会处理它。

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

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

答案 2 :(得分: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";