我有一个关于此代码片段的问题要问您:
window.location.hash=1;
$(window).on('hashchange', function() {
alert('hello');
});
上面的脚本应该执行以下操作:
- 将位置哈希设置为
1
- 任何进一步的改变->
alert('hello')
这就是问题所在:为什么hashchange
在第一次执行的第一次调用?这个脚本不应该只改变哈希值而不发出任何警报吗?
我该如何修复它,使其按描述工作?
首先,你问:
why is hashchange
在第一次执行的第一次调用?这个脚本不应该只改变哈希值而不发出任何警报吗?
为了回答这个问题,我们可以深入研究规范 http://www.w3.org/TR/html5/browsers.html。当导航到新片段时(即设置document.location.hash
), 规格 http://www.w3.org/TR/html5/browsers.html#navigate-fragid经历许多步骤,其中之一是:
- 遍历历史到新条目,与异步事件标志集。这将滚动到当前文档地址中给出的片段标识符。
规格为穿越历史 http://www.w3.org/TR/html5/browsers.html#traverse-the-history继续说道:
- If the asynchronous events flag is not set, then run the following steps synchronously. Otherwise, the asynchronous events flag is set; queue a task to run the following substeps.
- 如果 statechanged 为 true,则使用 PopStateEvent 接口在 Document 的 Window 对象上触发名为 popstate 的可信事件,并将 state 属性初始化为 state 的值。该事件必须冒泡,但不可取消,并且没有默认操作。
-
如果 hashchange 为 true,则触发名为 hashchange 的可信事件在浏览上下文的 Window 对象中,使用 HashChangeEvent 接口,其中 oldURL 属性初始化为旧 URL,newURL 属性初始化为新 URL。该事件必须冒泡,但不可取消,并且没有默认操作。
因此,所有这些加在一起意味着当您运行代码时,事件侦听器hashchange
将在步骤 14 的子步骤中的代码运行之前添加,并随后在设置哈希值时触发。
我该如何修复它,使其按描述工作?
要修复此问题,您还可以使用以下命令对事件侦听器的添加进行排队setTimeout(.., 0) https://stackoverflow.com/questions/779379/why-is-settimeoutfn-0-sometimes-useful:
setTimeout(function() {
$(window).on('hashchange', function() {
alert('hello');
});
}, 0);
由于您在设置哈希后将其添加到队列中,因此它将在上面步骤 14 中排队的任务之后添加到队列中,因此事件侦听器仅在事件触发后才会添加。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)