jquery: change the URL address without redirecting? [duplicate]

Solution 1:

NOTE: history.pushState() is now supported - see other answers.

You cannot change the whole url without redirecting, what you can do instead is change the hash.

The hash is the part of the url that goes after the # symbol. That was initially intended to direct you (locally) to sections of your HTML document, but you can read and modify it through javascript to use it somewhat like a global variable.


If applied well, this technique is useful in two ways:

  1. the browser history will remember each different step you took (since the url+hash changed)
  2. you can have an address which links not only to a particular html document, but also gives your javascript a clue about what to do. That means you end up pointing to a state inside your web app.

To change the hash you can do:

document.location.hash = "show_picture";

To watch for hash changes you have to do something like:

window.onhashchange = function(){
    var what_to_do = document.location.hash;    
    if (what_to_do=="#show_picture")
        show_picture();
}

Of course the hash is just a string, so you can do pretty much what you like with it. For example you can put a whole object there if you use JSON to stringify it.

There are very good JQuery libraries to do advanced things with that.

Solution 2:

See here - http://my.opera.com/community/forums/topic.dml?id=1319992&t=1331393279&page=1#comment11751402

Essentially:

history.pushState('data', '', 'http://your-domain/path');

You can manipulate the history object to make this work.

It only works on the same domain, but since you're satisfied with using the hash tag approach, that shouldn't matter.

Obviously would need to be cross-browser tested, but since that was posted on the Opera forum I'm safe to assume it would work in Opera, and I just tested it in Chrome and it worked fine.

Solution 3:

That site makes use of the "fragment" part of a url: the stuff after the "#". This is not sent to the server by the browser as part of the GET request, but can be used to store page state. So yes you can change the fragment without causing a page refresh or reload. When the page loads, your javascript reads this fragment and updates the page content appropriately, fetching data from the server via ajax requests as required. To read the fragment in js:

var fragment = location.hash;

but note that this value will include the "#" character at the beginning. To set the fragment:

location.hash = "your_state_data";