当前位置: 首页 > 知识库问答 >
问题:

理解hashchange事件的执行顺序

有宏峻
2023-03-14

关于此代码段,我有一个问题要问您:

window.location.hash=1;

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

上面的脚本应该这样做:

  1. 设置位置哈希为1
  2. 在任何进一步的变化-

这就是问题所在:为什么在第一次执行时调用hashchange?这个脚本不应该只更改哈希而不更改任何警报吗?

我如何修复它,使其按描述工作?

共有3个答案

章侯林
2023-03-14

另一种不调用setTimeout的方法是注册hashChange事件,然后设置hash的值。

$(window).on("hashchange",function() 
{
  alert('Invoked due to hash change' + window.location.hash);
});

alert('Hash Updated');
window.location.hash = "1";

小提琴:http://jsfiddle.net/86829ryz/10/

锺离玮
2023-03-14

在代码中使用计数器:

var counter = 0;

$(window).on('hashchange', function() {
    if (counter)
        alert('hello');
    counter++;
});
祁英哲
2023-03-14

首先,你问:

为什么在第一次执行时调用hashchange?这个脚本不应该只更改哈希而不更改任何警报吗?

为了回答这个问题,我们可以深入研究规范。当导航到一个新片段(即设置document.location.hash)时,规范会经过许多步骤,其中一个步骤是:

穿越历史的规范接着说:

  1. 如果状态更改为true,则使用PopState事件接口在文档的Windows对象处触发名为popstate的可信事件,并将state属性初始化为state的值。此事件必须冒泡,但不能取消,并且没有默认操作。
  2. 如果哈希更改为true,则使用HashChange事件接口,将oldURL属性初始化为旧URL,将newURL属性初始化为新URL,在浏览上下文的Windows对象处触发名称为hashChange的可信事件。此事件必须冒泡,但不能取消,并且没有默认操作。

因此,所有这些加在一起意味着,当您运行代码时,将在步骤14的子步骤中的代码运行之前添加hashChange的事件侦听器,并在设置散列时随后触发。

我如何修复它,使其按描述工作?

要解决此问题,您还可以使用setTimeout(..,0)将事件侦听器的添加排队:

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

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

 类似资料:
  • 事件函数执行顺序 在 Unity 脚本中,有大量的事件函数以特定的顺序被执行。执行顺序描述如下: 编辑器 Reset 当第一次把脚本绑定到对象上,或者使用了 Reset 命令时,该事件被触发,用以初始化脚本的属性。 加载第一个场景 当某个场景开始时,下面的事件被触发(场景中的每个对象都会执行一次): Awake 该函数总是在所有 Start 函数之前被调用,并且只会在某个 prefab 被实例化之

  • 如果我有以下代码: 对该循环中某个处理程序的所有调用是并行执行还是顺序执行?如果是顺序的,那么要获得并行执行,正确的方法是什么? 当做

  • 本文向大家介绍浅谈Java文件执行顺序、main程序入口的理解,包括了浅谈Java文件执行顺序、main程序入口的理解的使用技巧和注意事项,需要的朋友参考一下 在我们通过JVM编译Java后缀名的文件时,JVM首先寻找入口(main方法) 1、由于在入口时,未调用任何对象,该方法只能设置为static静态 2、JVM为Java的最底层,所以即使有返回结果,结果也无处可去,因此该方法必然是void无

  • 使用统一的控制脚本来初始化其他脚本 一般我都会有一个 Game.ts 的脚本作为总的控制脚本,假如我还有 Player.ts, Enemy.ts, Menu.ts 三个组件,那么他们的初始化过程是这样的: // Game.ts import { _decorator, Component, Node } from "cc"; const { ccclass, property } = _decor

  • 问题内容: 我有一棵divs树: 在div上单击时,将使其子级不可见-即单击“ a”将使“ b”和“ c”不可见。 问题是:单击“ b”将调用“ a”的单击,并使“ b”和“ c”不可见。如何使用jQuery禁用对“ a”的点击? 谢谢 问题答案: 您可以为孩子添加一个处理程序,以防止click事件蔓延: 这样一来,点击不会传播到。都不会单击以转到,因此也不会。

  • Hprose 中间件的顺序执行是按照添加的前后顺序执行的,假设添加的中间件处理器分别为:handler1, handler2 … handlerN,那幺执行顺序就是 handler1, handler2 … handlerN。 不同类型的 Hprose 中间件和 Hprose 其它过程的执行流程如下图所示: +--------------------------------------------