89

I am using:

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

to bind a function to the hash change event. This seems to work in IE8, Firefox and Chrome, but not in Safari and I assume not in earlier version of IE. For these browsers, I want to disable my JavaScript code that uses the hash and hashchange event.

Is there a way with jQuery that i can detect if the browser supports the hashchange event? Maybe something with jQuery.support...

Volker E.
  • 5,911
  • 11
  • 47
  • 64
Ian Herbert
  • 891
  • 1
  • 6
  • 3
  • 4
    [jQuery hashchange event](http://benalman.com/projects/jquery-hashchange-plugin/) - jQuery plugin works perfect, even in IE8. + it's very easy to use it :) – enloz Sep 16 '11 at 03:38

12 Answers12

70

You can detect if the browser supports the event by:

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

See also:

Christian C. Salvadó
  • 807,428
  • 183
  • 922
  • 838
47

An updated answer here as of 2017, should anyone need it, is that onhashchange is well supported in all major browsers. See caniuse for details. To use it with jQuery no plugin is needed:

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

Occasionally I come across legacy systems where hashbang URL's are still used and this is helpful. If you're building something new and using hash links I highly suggest you consider using the HTML5 pushState API instead.

Kevinleary.net
  • 8,851
  • 3
  • 54
  • 46
19

There is a hashchange plug-in which wraps up the functionality and cross browser issues available here.

James Westgate
  • 11,306
  • 8
  • 61
  • 68
18

A different approach to your problem...

There are 3 ways to bind the hashchange event to a method:

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

Or

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

Or

<body onhashchange="doThisWhenTheHashChanges();">

These all work with IE 9, FF 5, Safari 5, and Chrome 12 on Win 7.

james.garriss
  • 12,959
  • 7
  • 83
  • 96
8

try Mozilla official site: https://developer.mozilla.org/en/DOM/window.onhashchange

cite as follow:

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

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

window.onhashchange = locationHashChanged;
Dan Short
  • 9,598
  • 2
  • 28
  • 53
Paul Lan
  • 665
  • 2
  • 9
  • 12
3

I just ran into the same problem (lack of hashchange event in IE7). A workaround that suited for my purposes was to bind the click event of the hash-changing links.

<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>
johnny.rodgers
  • 1,347
  • 1
  • 11
  • 12
3

What about using a different way instead of the hash event and listen to popstate like.

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

This method works fine in most browsers i have tried so far.

Sven van den Boogaart
  • 11,833
  • 21
  • 86
  • 169
3

Note that in case of IE 7 and IE 9 if statment will give true for ("onhashchange" in windows) but the window.onhashchange will never fire, so its better to store hash and check it after every 100 millisecond whether its changed or not for all versions of 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);
    }
Ivan Durst
  • 1,163
  • 2
  • 12
  • 24
Khan Salahuddin
  • 585
  • 4
  • 4
  • 2
    Isn't this too much for the browser to handle? to poll for a hash change every 100ms? – adardesign Jul 06 '11 at 17:53
  • 5
    your sample code made my IE8 alerting until i opened task manager and killed process :) – enloz Sep 16 '11 at 03:29
  • that's because there's a typo, instead of "storedHash" use "prevHash" and it will work. He basically used a different variable name from how it's been declared. – Nick Sep 26 '13 at 05:57
1

this tiny jQuery plugin is very simple to use: https://github.com/finnlabs/jquery.observehashchange/

Morteza
  • 2,097
  • 5
  • 28
  • 47
0

Use Modernizr for detection of feature capabilities. In general jQuery offers to detect browser features: http://api.jquery.com/jQuery.support/. However, hashchange is not on the list.

The wiki of Modernizr offers a list of libraries to add HTML5 capabilities to old browsers. The list for hashchange includes a pointer to the project HTML5 History API, which seems to offer the functionality you would need if you wanted to emulate the behavior in old browsers.

koppor
  • 19,079
  • 15
  • 119
  • 161
0

Here is updated version of @johnny.rodgers

Hope helps someone.

// 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);
}
Deniz Porsuk
  • 492
  • 1
  • 6
  • 20
0

I think Chris Coyier has solution for that hashing problem, have a look at his screencast:

Best Practices with Dynamic Content

Sarfraz
  • 377,238
  • 77
  • 533
  • 578