关于此代码段,我有一个问题:
window.location.hash=1;
$(window).on('hashchange', function() {
alert('hello');
});
上面的脚本应该这样做:
1
alert('hello')
这是问题:为什么在第一次执行时第一次调用hashchange
?这个脚本不应该只更改哈希而没有任何警报吗?
如何修复它以使其按照描述工作?
答案 0 :(得分:3)
首先,你问:
为什么在第一次执行时第一次调用
hashchange
?这个脚本不应该只更改哈希而没有任何警报吗?
要回答这个问题,我们可以delve into the specification。导航到新片段(即设置document.location.hash
)时,the specification会经历多个步骤,其中一个步骤是:
- 将历史记录遍历到新条目,并设置异步事件标记。这将滚动到现在文档地址中给出的片段标识符。
醇>
traversing the history的规范继续说:
- 如果未设置异步事件标志,则同步运行以下步骤。 否则,设置异步事件标志;将任务排队以运行以下子步骤。
醇>
- 如果状态更改为true,则使用PopStateEvent接口在Document的Window对象上触发名为popstate的受信任事件,并将state属性初始化为state的值。此事件必须冒泡但不可取消,并且没有默认操作。
- 如果散列更改为true,则使用HashChangeEvent接口在浏览上下文的Window对象中触发名为hashchange 的受信任事件,并将oldURL属性初始化为旧URL并初始化newURL属性到新的URL。此事件必须冒泡但不可取消,并且没有默认操作。
因此,所有这些结合在一起意味着当您运行代码时,{I}的事件侦听器将在步骤14的子步骤中的代码运行之前添加,并且随后将在设置哈希时触发
如何修复它以使其按照描述工作?
要修复此问题,您还可以使用setTimeout(.., 0)
hashchange
由于您在设置散列后将其添加到队列中,因此在上面的步骤14中排队的任务之后,它将被添加到队列中,因此仅在事件被触发后才添加事件侦听器。
答案 1 :(得分:0)
在代码中使用计数器:
var counter = 0;
$(window).on('hashchange', function() {
if (counter)
alert('hello');
counter++;
});
答案 2 :(得分:0)
在不调用setTimeout的情况下修复它的另一种方法是注册'hashchange'事件,然后设置hash的值。
$(window).on("hashchange",function()
{
alert('Invoked due to hash change' + window.location.hash);
});
alert('Hash Updated');
window.location.hash = "1";