dojo/hash

since:1.4

dojo/hash provides methods for monitoring and updating the hash (history) in the browser URL as well as back/forward support and bookmarkability for dynamic web applications.

Introduction

dojo/hash is designed to make it easier to manage the browser history (hash) as well a provide cross-browser ways to support dynamic backwards and forwards navigation and bookmarkability. This allows for creating of dynamic web applications that can be navigable both in a non-linear fashion, but allows for you to provide your users with a “URL” to be able to return to a particular point in the application without actually doing a full page reload.

HTML5 defines an onhashchange event that fires when the value of the hash segment of the URL changes. See HTML5 History. dojo/hash uses the native onhashchange event if the browser supports it, and emulates this support for older browsers using a polling loop.

Usage

Running code when the browser hash changes works by loading the dojo/hash module and then subscribing to the appropriate topic:

require(["dojo/hash", "dojo/topic"], function(hash, topic){
  topic.subscribe("/dojo/hashchange", function(changedHash){
    // Handle the hash change publish
  });
});

The value of the change of the hash will be passed as the first argument.

To manipulate the value of the hash, simply call dojo/hash with the new value. It will be added to the browser history stack and it will publish a /dojo/hashchange topic, triggering anything subscribed:

require(["dojo/hash"], function(hash){
  hash("someURL");
});

In order to not to add to the history stack, pass true as the second parameter (replace). This will update the current browser URL and replace the current history state:

require(["dojo/hash"], function(hash){
  hash("someURL", true);
});

To get the current value of the hash, simply call the function without any arguments:

require(["dojo/hash"], function(hash){
  var currentHash = hash();
});

Examples

  1. Subscribe to the hashchange event:

    require(["dojo/topic", "dojo/hash"], function(topic, hash){
        topic.subscribe("/dojo/hashchange", context, callback);
    });
    
  2. Set the hash using query notation:

    require(["dojo/hash", "dojo/io-query"], function(hash, ioQuery){
        var obj = {
            firstParam: true,
            secondParam: false
        }
        hash(ioQuery.objectToQuery(obj));
    });
    
Hash: #firstParam=true&secondParam=false
  1. Parse this hash and add a parameter using query notation:

Initial hash: #firstParam=true&secondParam=false

require(["dojo/hash", "dojo/io-query"], function(hash, ioQuery){
    function updateHash(){
        var obj = ioQuery.queryToObject(hash());  // get
        obj.someNewParam = true;
        hash(ioQuery.objectToQuery(obj));  // set
    }
});

End hash: #firstParam=true&secondParam=false&someNewParam=true

  1. React to hashchange event (hash passed to callback as first param):

    require(["dojo/hash", "dojo/io-query"], function(hash, ioQuery){
        function callback(hash){
            // hashchange event!
            var obj = ioQuery.queryToObject(hash);
            if(obj.firstParam){
                // do something
            }
        }
    });
    
  2. Get and set the hash using slash notation:

Initial hash: #/firstSegment/secondSegment

require(["dojo/hash"], function(hash){
    function updateHash(){
        var obj = hash().split("/");
        obj.push("trailingSegment");
        hash(obj.join("/"));
    }
});

End hash: #/firstSegment/secondSegment/trailingSegment

Notes

Customizing the Polling Loop Frequency

For browsers that do not support the onhashchange event natively, a polling loops monitors the URL for changes. The default duration of this polling loop is 100 ms. To customize this value, add hashPollFrequency to dojo config.

dojoConfig = { hashPollFrequency: 200 };

Encoding/Decoding

dojo/hash does not attempt to do any encoding or decoding. There are many cases where consumers of dojo/hash want unencoded slashes, etc, so it is up to the consumer to encode and decode where appropriate. Anything with HTML encoding (e.g. &) must be encoded with encodeURIComponent before being passed into dojo/hash due to discrepancies between browsers. For example Firefox decodes HTML encoding automatically before setting the URL, IE does not.

require(["dojo/hash"], function(hash){
  hash(encodeURIComponent("hash with & HTML encoding"));
});

See Also

  • dojo/back - Module for handling browser “back” events.
  • dojo/io-query - Module the contains URL processing functions.
  • dojo/router - Module that provides mapping of a hash to a callback.
Error in the documentation? Can’t find what you are looking for? Let us know!