当用户更改页面的哈希值时,我使用window.onhashchange函数执行代码:
window.onhashchange = function() { /* do something */ };
在某些功能中,我还通过JavaScript设置哈希:
window.location.hash = "#abc";
当我通过JavaScript设置哈希时,我想阻止触发onhashchange事件。
到目前为止我尝试过:
var currently_setting_hash = false;
window.onhashchange = function() {
if (currently_setting_hash)
return;
//...
}
currently_setting_hash = true;
window.location.hash = "#abc";
currently_setting_hash = false;
这不起作用,因为事件被延迟触发,因此代码将首先设置哈希值,然后将“currently_setting_hash”设置为false,然后执行onhashchange事件。
有关如何实现这一目标的任何想法?或者有没有办法检测哈希是由用户还是通过JavaScript设置的?
答案 0 :(得分:8)
您可以从事件处理程序本身重置变量:
var currently_setting_hash = false;
$(window).on("hashchange", function() {
if (currently_setting_hash) {
currently_setting_hash = false;
return;
}
currently_setting_hash = false;
//...
});
currently_setting_hash = true;
window.location.hash = "#abc";
答案 1 :(得分:4)
由于事件被延迟,事件可能以不同于您预期的顺序发生(例如,想象用户在代码执行之前或之后通过其他方式更改URL)。重要的是通过假设事件是你的来确保你不会变得不一致。因此我有一个建议(基于你的代码和Adam Bubela的):
var expectedHash;
window.onhashchange = function () {
if (window.location.hash === expectedHash) {
return;
}
expectedHash = window.location.hash;
// ... do actual reaction to change here ...
}
function changeHash(hash) {
hash = canonicalizeHashValue(hash);
expectedHash = hash;
window.location.hash = hash;
}
// Helper - return the version of the URL that the browser is expected to
// so that the equality test is accurate.
function canonicalizeHashValue(value) {
// Borrowing an A element's ability to resolve/parse URLs.
var tmp = document.createElement('a');
tmp.href = "";
tmp.hash = value;
return tmp.hash;
}
仅当更改到您期望的值时,此代码才会禁止更改处理程序。 (onhashchange
内部的赋值确保如果哈希临时转到另一个值,处理程序也会运行,我认为这比另一个更正确。)
只有在指定非规范值时才需要第三个辅助函数canonicalizeHashValue
,例如: changeHash('foo')
代替changeHash('#foo')
。
答案 2 :(得分:3)
如果你想使用普通的Javascript:
答案 3 :(得分:0)
好吧,因为事件被延迟,如果你不止一次更改哈希(出于任何原因),那么会有更多事件连续发生。在这种情况下,每次更改哈希值时都应该增加一个整数。
var setting_hash = 0;
window.onhashchange = function() {
if (setting_hash){
setting_hash--;
return;
}
//code here
}
function changeHash(hash) {//hash without '#'
if (hash!=window.location.hash.substr(1)) {
setting_hash++;
}
window.location.hash = hash;
}
答案 4 :(得分:0)
现在您可以使用 History.replaceState() 方法。它在不触发“onhashchange”的情况下替换散列。
window.onhashchange = function() { /* do something */ };
// ...
history.replaceState(undefined,undefined,'#1234'); // This will replace the hash without triggering 'onhashchage'.