jQuery - hashchange事件

91

我正在使用:

$(window).bind( 'hashchange', function(e) { });

如何将一个函数绑定到URL的hash值改变事件上?这个方法看起来在IE8、Firefox和Chrome中能够使用,但是在Safari和较早版本的IE中似乎不行。对于这些浏览器,我希望禁用使用hash和hashchange事件的JavaScript代码。

有没有一种使用jQuery的方式可以检测浏览器是否支持hashchange事件?也许可以使用jQuery.support...


4
jQuery哈希变化事件 - 这个jQuery插件非常完美,即使在IE8中也能很好地工作。而且使用起来非常简单 :) - enloz
12个回答

71

谢谢您的回复,而且还很快。 - Ian Herbert
19
请注意,以IE7兼容模式运行的IE8在window对象中对'onhashchange'事件返回true,即使该事件不被支持。-来自jQuery Mobile - Vikas

49

更新于2017年的答案是,onhashchange 在所有主流浏览器中都得到了很好的支持。有关详细信息,请参见 caniuse 。要在jQuery 中使用它,不需要任何插件:

$( window ).on( 'hashchange', function( e ) {
    console.log( 'hash changed' );
} );

有时我会遇到仍在使用hashbang URL的旧系统,这很有帮助。如果您正在构建新内容并使用哈希链接,请强烈建议您考虑改用HTML5 pushState API。


3
可以使用 window.location.hash 访问当前的哈希值,这个方法运作良好。 - Daniel Dewhurst

19

仅适用于< IE8 - James Westgate

18

针对您的问题,有一种不同的方法...

将hashchange事件绑定到方法有三种方式:

<script>
    window.onhashchange = doThisWhenTheHashChanges;
</script>

或者

<script>
    window.addEventListener("hashchange", doThisWhenTheHashChanges, false);
</script>

或者

<body onhashchange="doThisWhenTheHashChanges();">

这些代码适用于在Win 7上的IE 9、FF 5、Safari 5和Chrome 12浏览器中运行。


8

请尝试访问Mozilla官方网站:https://developer.mozilla.org/en/DOM/window.onhashchange

引用如下:

if ("onhashchange" in window) {
    alert("The browser supports the hashchange event!");
}

function locationHashChanged() {
    if (location.hash === "#somecoolfeature") {
        somecoolfeature();
    }
}

window.onhashchange = locationHashChanged;

3
请注意,对于IE 7和IE 9,如果语句("onhashchange" in windows)为真,则window.onhashchange将永远不会触发。因此,最好在所有版本的IE中存储哈希并检查它是否已更改每100毫秒一次。
    if (("onhashchange" in window) && !($.browser.msie)) { 
         window.onhashchange = function () { 
              alert(window.location.hash);             
         }            
         // Or $(window).bind( 'hashchange',function(e) {  
         //       alert(window.location.hash); 
         //   });              
    }
    else { 
        var prevHash = window.location.hash;
        window.setInterval(function () {
           if (window.location.hash != prevHash) {
              prevHash = window.location.hash;
              alert(window.location.hash);
           }
        }, 100);
    }

2
浏览器处理这么多的事情不会太多了吗?每100毫秒轮询哈希变化? - adardesign
5
你的示例代码让我的IE8一直弹出警告,直到我打开任务管理器并终止进程 :) - enloz
这是因为有一个打字错误,应该使用“prevHash”而不是“storedHash”,这样就可以正常工作了。他基本上使用了与声明方式不同的变量名。 - Nick

3

我也遇到了同样的问题(IE7中缺少hashchange事件)。一个适合我使用的解决方法是绑定哈希变化链接的单击事件。

<a class='hash-changer' href='#foo'>Foo</a>

<script type='text/javascript'>

if (("onhashchange" in window) && !($.browser.msie)) { 

    //modern browsers 
    $(window).bind('hashchange', function() {
        var hash = window.location.hash.replace(/^#/,'');
        //do whatever you need with the hash
    });

} else {

    //IE and browsers that don't support hashchange
    $('a.hash-changer').bind('click', function() {
        var hash = $(this).attr('href').replace(/^#/,'');
        //do whatever you need with the hash
    });

}

</script>

1
你可以使用 $('a[href^="#"]') 来获取以井号开头的 href 链接,避免需要添加类。 - tobymackenzie

3

除了使用哈希事件外,尝试使用另一种方式监听popstate事件如何?

window.addEventListener('popstate', function(event)
{
    if(window.location.hash) {
            var hash = window.location.hash;
            console.log(hash);
    }
});

这种方法在我试过的大多数浏览器中都可以正常工作。


1
Popstate比hashchange还要新。例如,它不支持IE < 10。 - Arturo Torres Sánchez

1

0

这是更新版本的@johnny.rodgers

希望能对某些人有所帮助。

// ie9 ve ie7 return true but never fire, lets remove ie less then 10
if(("onhashchange" in window) && navigator.userAgent.toLowerCase().indexOf('msie') == -1){ // event supported?
    window.onhashchange = function(){
        var url = window.location.hash.substring(1);
        alert(url);
    }
}
else{ // event not supported:
    var storedhash = window.location.hash;
    window.setInterval(function(){
        if(window.location.hash != storedhash){
            storedhash = window.location.hash;
            alert(url);
        }
    }, 100);
}

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