Skip to content

Instantly share code, notes, and snippets.

@brombal
Last active May 17, 2016 17:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brombal/473cffa71842328e9160919a463919f7 to your computer and use it in GitHub Desktop.
Save brombal/473cffa71842328e9160919a463919f7 to your computer and use it in GitHub Desktop.
hashbang.js provides simple URL monitoring from fragment (hash) changes.

hashbang.js monitors the URL fragment (hashtag) for changes and invokes callbacks when they occur. You can specify a fragment as a string or a regular expression, and callbacks that should be fired when the fragment appears and disappears from the URL.

Examples:

As a complete object, with both plain string and regular expression matches, and 'load' and 'unload' callbacks:

hashbang({
    '#home': {
        load: function() {
            // '#home' fragment appeared in the url
        },
        unload: function() {
            // browser navigated away from '#home'; 
            // 'newFragment' will contain the current fragment
        }
    },
    '/#(.*)/': {
        load: function() {
            // A fragment that matched the /#(.*)/ regular expression appeared in the url
        },
        unload: function() {
            // browser navigated away from the previously matched fragment; 
            // 'newFragment' will contain the current fragment
        }
    }
});

If you don't need any unload functions, you can reduce the example down to this:

hashbang({
    '#home': function() {
        // '#home' fragment appeared in the url
    },
    '/#(.*)/': function(fragment, matches) {
        // A fragment that matched the /#(.*)/ regular expression appeared in the url
        // 'fragment' will contain the entire fragment
        // 'matches' is the result of JavaScript's 'match' function (an array of match groups)
    }
});

If you only need to match one fragment, you can pass the fragment matcher and callbacks as individual parameters instead of an object:

hashbang(
    '#home', 
    
    // 'load' callback
    function() { 
        // '#home' fragment appeared in the url
    },
    
    // 'unload' callback (optional)
    function(newFragment) { 
        // browser navigated away from '#home'; 
        // 'newFragment' will contain the current fragment
    }
);

Other functions

  • hashbang.handle(defaultFragment)

    Hashbang.js does not automatically handle the fragment in the url when the page loads. Call this method to handle the current fragment. defaultFragment - If no fragment is present in the current url, hashbang.js will treat it as if this fragment was present instead.

    // This will process the current location's fragment, or '#home' if no fragment is in the current url.
    hashbang.handle('#home');
  • hashbang.go(fragment, enableHistory)

    Use this method to send the user to a specific url fragment. fragment - the fragment to navigate to (including the # symbol) enableHistory - true to add the new url to the user's browser history, false to "silently" navigate.

(function(undefined) {
window.hashbang = function (match, load, unload) {
var handlers = null;
if (match.constructor == Object)
for (var i in match) {
if (match[i].constructor == Function) hashbang(i, match[i]);
else if (match[i].load) hashbang(i, match[i].load, match[i].unload);
}
else {
var str = match.toString();
if ((str[0] || str.substr(0, 1)).match(/[#\/]/))
hashbang.handlers[str] = { load: load, unload: unload };
}
return hashbang.handlers;
};
hashbang.handlers = {};
hashbang.handle = function (_default) {
if (_default !== undefined) hashbang._default = _default;
var hash = window.location.hash || hashbang._default || '#';
if (hashbang.unload) hashbang.unload(hash);
hashbang.unload = null;
var handler = null;
var matches = undefined;
for (var i in hashbang.handlers) {
if ((i[0] == '#' && hash == i)
|| (i[0] == '/' && (matches = hash.match(new RegExp(i.replace(/(^\/|\/$)/g, '')))))) {
handler = hashbang.handlers[i];
break;
}
}
if (!handler) handler = hashbang.handlers[_default];
if (!handler) return;
hashbang.unload = handler.unload;
handler.load(hash, matches);
};
hashbang.go = function (hash, history) {
if (history)
window.location.href = window.location.pathname + window.location.search + hash;
else
window.location.replace(window.location.pathname + window.location.search + hash);
return false;
};
$(window).on('hashchange', function() { hashbang.handle(); });
$(window).on('click', 'a', function () {
if ($(this).attr('href')[0] == '#')
return hashbang.go($(this).attr('href'), !$(this).data('history'));
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment