如何使用JavaScript检测地址栏的变化?

31

我有一个很重的Ajax应用程序,可能具有类似于以下的URL

http://example.com/myApp/#page=1

当用户操作网站时,地址栏可能会变成类似于以下内容:

http://example.com/myApp/#page=5

不重新加载页面。

我的问题是以下步骤:

  1. 用户收藏第一个URL。
  2. 用户操作应用程序,使第二个URL成为当前状态。
  3. 用户单击在步骤1中创建的书签。
  4. 地址栏中的URL从http://example.com/myApp/#page=5更改为http://example.com/myApp/#page=1,但我不知道如何检测更改发生了什么。

如果我检测到更改,一些JavaScript代码将对其进行处理。


我很好奇,这个应用程序为什么要设计成这样?我看不出来实际上需要更改URL。 - Vinko Vrsalovic
它的工作方式就像查询字符串一样,但不会导致浏览器重新加载页面。这样做是为了避免每次更改页面时都要检索和加载客户端的有效负载。有效负载不容易缓存,需要大量的JavaScript初始化时间,并且不能为客户端提供无缝体验。 - JoshNaro
4个回答

42

HTML5引入了hashchange事件,使您可以注册以获取URL哈希更改的通知,而无需使用计时器轮询它们。

它受到所有主流浏览器的支持(Firefox 3.6、IE8、Chrome和其他基于Webkit的浏览器),但我仍然强烈建议使用一个能够为您处理事件的库-例如,在不支持HTML5事件的浏览器中使用计时器,在其他情况下使用事件。

window.onhashchange = function() {
    alert("hashtag changed");
};

如需更多有关该事件的信息,请参阅 https://developer.mozilla.org/en/dom/window.onhashchangehttp://msdn.microsoft.com/en-us/library/cc288209%28VS.85%29.aspx


1
现在只要那些IE6/7用户都升级到>=IE8就好了。感谢更新。 - JoshNaro
我开始使用hashChange事件的jqouery插件 - 一切都运行得很顺利 :D - JJschk

20

使用setTimeout/interval定期检查当前地址:

 var oldLocation = location.href;
 setInterval(function() {
      if(location.href != oldLocation) {
           // do your action
           oldLocation = location.href
      }
  }, 1000); // check every second

1
这个答案是正确的。你还应该考虑使用像YUI历史管理器组件这样的东西,它可以为你在跨浏览器的情况下完成这项工作。 - Jonathan Feinberg
2
是的,我希望有一个隐藏的事件或其他什么东西。使用间隔对我来说似乎不太“正确”。谢谢。 - JoshNaro
1
这很丑,但显然是唯一的方法:https://dev59.com/A3A75IYBdhLWcg3wAUF9 - user2398029
有人能解释一下这个怎么可能会起作用吗?当我改变地址栏中的地址时,浏览器会获取一个新页面,并且旧页面被销毁,所以这个函数永远不会有机会运行。 - Mike Nakis
1
@MikeNakis 这个问题的前提是你所描述的情况并没有发生。页面以某种动态的方式进行更改,URL也在变化,但页面从未被拆除。 - ojchase
显示剩余3条评论

6
你应该扩展位置对象以公开可以绑定的事件。
例如:
window.location.prototype.changed = function(e){};

(function() //create a scope so 'location' is not global
{
    var location = window.location.href;
    setInterval(function()
    {
        if(location != window.location.href)
        {
            location = window.location.href;
            window.location.changed(location);
        }
    }, 1000);
})();

window.location.changed = function(e)
{
    console.log(e);//outputs http://newhref.com
    //this is fired when the window changes location
}

1
实际上,由于它使用计时器,它并没有真正带来任何关于所选解决方案的增强。 - jmd
1
将已经公开了可以观察的值的全局对象扩展并不是最好的想法。 - Trendy

0

SWFaddress 是这些事情的一个非常出色的库。


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