Hashchange 事件侦听器在事件处理程序附加到事件之前侦听
Hashchange event listener listens before event handler is attached to event
我有以下代码
console.info('checking if url contains hash');
if (!location.hash) {
console.warn('if-block replacing hash to empty!');
location.href = '#';
// Running route() to trigger Router.otherwise()
console.info('running route() from if-block(hash doesn\'t exist)');
route(location.hash.slice(1));
} else {
// URL contains a hash. Running Router.when() to load template
console.info('running route() from else-block(hash already present in url)');
route(location.hash.slice(1));
}
// Bind hashchange-event to window-object... duh
console.info('binding hashchange event');
$(window).on('hashchange', function () {
console.info('running route() from hashchange');
route(location.hash.slice(1));
});
很明显,事件侦听器附加在 else-if 块之后。我的控制台输出证实了这一点
2015-02-13 12:51:14.281 main.js:69 checking if url contains hash
2015-02-13 12:51:14.284 main.js:71 if-block replacing hash to empty!
2015-02-13 12:51:14.290 main.js:75 running route() from if-block(hash doesn\'t exist)
2015-02-13 12:51:16.677 main.js:84 binding hashchange event
2015-02-13 12:51:16.678 main.js:86 running route() from hashchange
看起来事件侦听器以某种方式获取了先前触发的 hashchange 事件。
这仅在 url 为 example.com
而非 example.com/#
时发生。如果 /
或 /#
在您进入该站点时从 url 中丢失,则会触发此现象。
编辑:我遇到的问题是 hashchange
事件侦听器甚至在侦听哈希更改之前就已触发。我想知道这是否正常。
另一个编辑:
一个更清楚的例子表明,当我第一次 运行 getEventListeners(window)
时,没有听众附加到 hashchange
事件。尽管如此,当我添加事件侦听器时,它会拾取先前触发的 hashchange
我是不是遗漏了什么或者发生了什么事?
有什么办法可以绕过这个吗?
让我们将您的代码简化为
location.hash = 'foobar';
window.onhashchange = function() {
document.body.innerHTML = 'You should not see me. But you do :(';
};
要解决这个问题,您可以使用setTimeout
延迟事件处理程序的添加:
location.hash = 'foobar';
setTimeout(function(){ // Delayed code
window.onhashchange = function() {
document.body.innerHTML = 'You should not see me. And you do not :)';
};
}, 0);
我有以下代码
console.info('checking if url contains hash');
if (!location.hash) {
console.warn('if-block replacing hash to empty!');
location.href = '#';
// Running route() to trigger Router.otherwise()
console.info('running route() from if-block(hash doesn\'t exist)');
route(location.hash.slice(1));
} else {
// URL contains a hash. Running Router.when() to load template
console.info('running route() from else-block(hash already present in url)');
route(location.hash.slice(1));
}
// Bind hashchange-event to window-object... duh
console.info('binding hashchange event');
$(window).on('hashchange', function () {
console.info('running route() from hashchange');
route(location.hash.slice(1));
});
很明显,事件侦听器附加在 else-if 块之后。我的控制台输出证实了这一点
2015-02-13 12:51:14.281 main.js:69 checking if url contains hash
2015-02-13 12:51:14.284 main.js:71 if-block replacing hash to empty!
2015-02-13 12:51:14.290 main.js:75 running route() from if-block(hash doesn\'t exist)
2015-02-13 12:51:16.677 main.js:84 binding hashchange event
2015-02-13 12:51:16.678 main.js:86 running route() from hashchange
看起来事件侦听器以某种方式获取了先前触发的 hashchange 事件。
这仅在 url 为 example.com
而非 example.com/#
时发生。如果 /
或 /#
在您进入该站点时从 url 中丢失,则会触发此现象。
编辑:我遇到的问题是 hashchange
事件侦听器甚至在侦听哈希更改之前就已触发。我想知道这是否正常。
另一个编辑:
一个更清楚的例子表明,当我第一次 运行 getEventListeners(window)
时,没有听众附加到 hashchange
事件。尽管如此,当我添加事件侦听器时,它会拾取先前触发的 hashchange
我是不是遗漏了什么或者发生了什么事?
有什么办法可以绕过这个吗?
让我们将您的代码简化为
location.hash = 'foobar';
window.onhashchange = function() {
document.body.innerHTML = 'You should not see me. But you do :(';
};
要解决这个问题,您可以使用setTimeout
延迟事件处理程序的添加:
location.hash = 'foobar';
setTimeout(function(){ // Delayed code
window.onhashchange = function() {
document.body.innerHTML = 'You should not see me. And you do not :)';
};
}, 0);