Home » Jquery » Change hash without triggering a hashchange event

Change hash without triggering a hashchange event

Posted by: admin November 30, 2017 Leave a comment

Questions:

I’m using the hash to load content dynamically. To make the back button work I am capturing hash changes. However sometimes I need to change the hash without triggering the hash changed function (eg, when the page was redirected server side and I need to update the hash once the content has returned.)

The best solution I have come up with is to unbind the hashchange event, make the change and then rebind it. However, as this happens asynchronously, I am finding that it rebinds too quickly and still catches the hash change.

My solution at the moment is very poor: Rebinding in a setTimeout. Does anyone have a better idea?

    $(window).unbind( 'hashchange', hashChanged);
    window.location.hash  = "!" + url;
    setTimeout(function(){
        $(window).bind( 'hashchange', hashChanged);
    }, 100);

Edit:
Amir Raminfar’s suggestion prompted me to a solution that does not require a timeout.
I added a class variable

_ignoreHashChange = false;

When I want to change the hash silently I do this:

_ignoreHashChange = true;
window.location.hash  = "!" + url;

and the hash changed event does this :

function hashChanged(event){
    if(_ignoreHashChange === false){
        url = window.location.hash.slice(2);
        fetchContent(url);
    }
    _ignoreHashChange = false;
}
Answers:

You can have a function like this:

function updateHash(newHash){
  ...
  oldHash = newHash
}

then in your setTimeOut you need to do

function(){
  if(oldHash != currenHash){
    updateHash(currenHash);
  }
}

So now you can call update hash manually and it won’t be triggered by the event. You can also have more parameters in updateHash to do other things.

By the way, have you looked at the jquery history plugin? http://tkyk.github.com/jquery-history-plugin/

Questions:
Answers:

You could use history.replaceState and append the hash, to replace the current URI without triggering the hashchange event:

var newHash = 'test';

history.replaceState(null, null, document.location.pathname + '#' + newHash);

JSFiddle example