javascript - 了解 hashchange 事件的执行顺序

标签 javascript jquery

我有一个关于这段代码的问题要问你:

window.location.hash=1;

$(window).on('hashchange', function() {
    alert('hello');
});

上面的脚本应该这样做:

  1. 将位置哈希设置为 1
  2. 任何进一步的变化 -> alert('hello')

问题来了:为什么在第一次执行的第一时间就调用了hashchange?这个脚本不应该只更改散列而没有任何警报吗?

我怎样才能修复它以使其如描述的那样工作?

最佳答案

首先,你问:

why is hashchange called at the first time of the first execution? Shouldn't this script change only the hash without any alert?

要回答这个问题,我们可以 delve into the specification .导航到新片段时(即设置 document.location.hash),the specification经历了很多步骤,其中之一是:

  1. Traverse the history to the new entry, with the asynchronous events flag set. This will scroll to the fragment identifier given in what is now the document's address.

traversing the history 的规范继续说:

  1. 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.
    1. If state changed is true, fire a trusted event with the name popstate at the Window object of the Document, using the PopStateEvent interface, with the state attribute initialized to the value of state. This event must bubble but not be cancelable and has no default action.
    2. If hash changed is true, then fire a trusted event with the name hashchange at the browsing context's Window object, using the HashChangeEvent interface, with the oldURL attribute initialized to old URL and the newURL attribute initialized to new URL. This event must bubble but not be cancelable and has no default action.

所有这些加在一起意味着当您运行代码时,hashchange 的事件监听器将在第 14 步的子步骤中的代码运行之前添加,随后将在哈希已设置。


How can I fix it so that it works as described?

要修复它,您还可以使用 setTimeout(.., 0) 将添加的事件监听器排队。 :

setTimeout(function() {
    $(window).on('hashchange', function() {
        alert('hello');
    });
}, 0);

由于您在设置哈希后将其添加到队列中,它将在上述步骤 14 中排队的任务之后添加到队列中,因此事件监听器仅在事件被触发后添加。

关于javascript - 了解 hashchange 事件的执行顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33087166/

相关文章:

javascript - 如何更改具有数据属性的特定 div 的内容?

jquery - 对齐 CSS Drop Down 的恼人问题

javascript - Uncaught SyntaxError : Unexpected token, not jsonp ¿but reading json?

jquery - 使用 jQuery 的页面加载器

javascript - 在 AngularJS 中使用工厂进行身份验证服务时 undefined object

javascript - 使用Winston Logger登录/var/log失败

javascript - 如何在node.js(Express)中使用通过res.render传递的字典

javascript - 当按下按钮进入输入时获取表格 div 内容

javascript - Oauth.io 服务和社交网络链接、取消链接?

javascript - 使用 Angular.js 预加载图像的最佳方法