jQuery - sự kiện hashchange


86

Tôi đang dùng:

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

để liên kết một hàm với sự kiện thay đổi băm. Điều này dường như hoạt động trong IE8, Firefox và Chrome, nhưng không hoạt động trong Safari và tôi cho rằng không phải trong phiên bản IE trước đó. Đối với các trình duyệt này, tôi muốn vô hiệu hóa mã JavaScript của mình sử dụng hàm băm và hashchangesự kiện.

Có cách nào với jQuery mà tôi có thể phát hiện xem trình duyệt có hỗ trợ hashchangesự kiện không? Có lẽ cái gì đó với jQuery.support...


4
Sự kiện jQuery hashchange - plugin jQuery hoạt động hoàn hảo, ngay cả trong IE8. + nó rất dễ sử dụng :)
enloz

Câu trả lời:


69

Bạn có thể phát hiện xem trình duyệt có hỗ trợ sự kiện hay không bằng cách:

if ("onhashchange" in window) {
  //...
}

Xem thêm:


Cảm ơn vì điều đó và phản hồi nhanh chóng.
Ian Herbert

19
Lưu ý rằng IE8 chạy ở chế độ tương thích IE7 báo cáo đúng với 'onhashchange' trong cửa sổ, mặc dù sự kiện không được hỗ trợ -từ jQuery Mobile
Vikas

35

Một câu trả lời được cập nhật ở đây kể từ năm 2017, nếu bất kỳ ai cần, là nó onhashchangeđược hỗ trợ tốt trong tất cả các trình duyệt chính. Xem caniuse để biết chi tiết. Để sử dụng nó với jQuery, không cần plugin:

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

Đôi khi tôi gặp các hệ thống cũ nơi URL hashbang vẫn được sử dụng và điều này rất hữu ích. Nếu bạn đang xây dựng thứ gì đó mới và sử dụng liên kết băm, tôi thực sự khuyên bạn nên cân nhắc sử dụng API HTML5 pushState thay thế.


2
Điều này hoạt động tốt, sử dụng window.location.hashđể truy cập hàm băm hiện tại.
Daniel Dewhurst


18

Một cách tiếp cận khác cho vấn đề của bạn ...

Có 3 cách để liên kết sự kiện băm với một phương thức:

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

Hoặc là

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

Hoặc là

<body onhashchange="doThisWhenTheHashChanges();">

Tất cả đều hoạt động với IE 9, FF 5, Safari 5 và Chrome 12 trên Win 7.


8

thử trang web chính thức của Mozilla: https://developer.mozilla.org/en/DOM/window.onhashchange

trích dẫn như sau:

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

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

window.onhashchange = locationHashChanged;

3

Tôi vừa gặp phải vấn đề tương tự (thiếu sự kiện hashchange trong IE7). Một giải pháp phù hợp với mục đích của tôi là ràng buộc sự kiện nhấp chuột của các liên kết thay đổi hàm băm.

<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
bạn có thể sử dụng $('a[href^="#"]')để có được các liên kết đến hrefs bắt đầu bằng một băm, tránh sự cần thiết cho một add lớp
tobymackenzie

2

Lưu ý rằng trong trường hợp của IE 7 và IE 9 nếu trạng thái sẽ trả về true cho ("onhashchange" trong windows) nhưng window.onhashchange sẽ không bao giờ kích hoạt, vì vậy tốt hơn hết bạn nên lưu trữ hàm băm và kiểm tra nó sau mỗi 100 mili giây xem nó có thay đổi hay không cho tất cả các phiên bản của IE.

    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
Điều này không phải là quá nhiều cho trình duyệt để xử lý? để thăm dò ý kiến ​​về sự thay đổi hàm băm sau mỗi 100ms?
adardesign

5
mẫu mã của bạn làm IE8 tôi cảnh báo cho đến khi tôi mở task manager và quá trình giết :)
enloz

đó là bởi vì có lỗi đánh máy, thay vì "ManagedHash", hãy sử dụng "prevHash" và nó sẽ hoạt động. Về cơ bản, anh ta đã sử dụng một tên biến khác với cách nó được khai báo.
Nick

2

Còn về việc sử dụng một cách khác thay vì sự kiện băm và nghe popstate như thế nào.

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

Phương pháp này hoạt động tốt trong hầu hết các trình duyệt mà tôi đã thử cho đến nay.


1
Popstate thậm chí còn mới hơn hashchange. Ví dụ: nó không được hỗ trợ trong IE <10
Arturo Torres Sánchez



0

Sử dụng Modernizr để phát hiện các khả năng của tính năng. Nói chung, jQuery cung cấp để phát hiện các tính năng của trình duyệt: http://api.jquery.com/jQuery.support/ . Tuy nhiên, hashchange không có trong danh sách.

Các wiki của Modernizr cung cấp một danh sách các thư viện để thêm các khả năng HTML5 để trình duyệt cũ. Các danh sách cho hashchange bao gồm một con trỏ đến các dự án HTML5 API lịch sử , mà dường như để cung cấp các chức năng bạn sẽ cần nếu bạn muốn bắt chước những hành vi trong các trình duyệt cũ.


0

Đây là phiên bản cập nhật của @ johnny.rodgers

Hy vọng sẽ giúp ai đó.

// 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);
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.