HTML5历史记录API - 不要在第一次页面加载时触发window.onpopstate事件

4
使用HTML5 History API,我创建了如下内容:
(function (d, w) {

    $(function () {

        $("#indicator").hide();

        if (typeof history.pushState !== 'undefined') { 

            $("#citylinks a").click(function (e) {
                history.pushState({ path: this.href }, '', this.href);
                act(this.href);
                e.preventDefault();
            });

            w.onpopstate = function (event) {
                act(d.location);
            };
        }

        function act(location) {

            $("#results").hide();
            $("#indicator").show();

            $.getJSON(location, function (data) {

                $("#results").html(data.result);
                $("#results").fadeIn();

                $("#indicator").hide();
            });
        }

    });

})(document, window);

完整代码在这里:

https://github.com/tugberkugurlu/MvcMiracleWorker/commit/7c511f20678bbfe15462909c794eb323ce615372#diff-3

我在这里遇到的问题是,我不想在页面第一次从服务器加载时触发w.onpopstate事件。
我想这样做的原因是我想在服务器端填充页面,而不想让客户端代码来完成。如果我删除w.onpopstate事件,我将无法捕获history.go()事件。
有没有解决这个问题的方法?
1个回答

4
一个非常简单的方法是这样的:
w.onpopstate = function () {
    w.onpopstate = function (event) {
        act(d.location);
    }
}

这意味着第一次触发onpopstate事件时,您的函数将被设置为事件处理程序(替换当前处理程序),从而在事件在页面加载时运行时创建一个noop

不错的解决方案。一个小问题是它在每个 windows.onpopstate 事件上都运行。我试图通过检查 window.onpopstate 事件是否为 nullundefined 来防止这种情况,但是没有成功。 - tugberk
2
考虑到Firefox在页面加载时不会触发onpopstate事件,那么这个函数是否会在有效的.back()/.forward()事件上首先被错误地设置? - LaserBeak
@LaserBeak:如果真是这样,那么在Firefox中,这段代码确实会有问题。由于OP从未说过哪个浏览器出现了这个问题,并且他随后将此答案标记为正确,我认为所有浏览器都共享相同的行为。如果不是这种情况,则其中一个或多个浏览器可能存在错误。 - Andy E
实际上看起来 Firefox 目前是唯一遵循标准的浏览器。Chrome 和 Safari 在第一次页面加载时会触发 onpopstate,因此它们不符合标准。 - Simone
1
Chrome 34金丝雀版中的漏洞已经修复。 - Binyamin
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接