3
\$\begingroup\$

I've built this small jQuery plugin to work with HTML5 History State functions. It's my first jQuery plugin, so I'm not sure if it's up to the best practices, or what could be done better. Keeping it simple and small is my main concern.

If you have any suggestions on how to improve it, I'd love to see them.

// FunkyHistory Plugin
(function ( $, window, document, undefined ) {
jQuery.fn.FunkyHistory = function( options, callback ) {

    // Don't do anything if History not supported
    if (!window.history && !window.history.pushState) {
        return this;
    }

    // These are the defaults.
    var settings = jQuery.extend({  
            target: null,
            selector: "body"
    }, options );

    // Prepare
    var FunkyHistory = {};
        FunkyHistory.selector = this.selector;
        FunkyHistory.clickedEl = null;

    // Update content on page
    FunkyHistory.loadNewContent = function(target, url, selector){

        jQuery.get(url, function(data) {

            // Update content on page
            var newContent = jQuery(data).find(selector);

            // Only update content if a target is set
            if( settings.target ) {
                jQuery(target).replaceWith(newContent);                 
            }

            // Callback
            if (typeof callback == 'function') { // make sure the callback is a function
                callback.call(FunkyHistory.clickedEl, data); // brings the scope to the callback
            }

        }, 'text');         
    }

    // When browser back/forward button is pressed      
    FunkyHistory.bindPopState = function(){
        jQuery(window).on('popstate',function(event){
            // Load in correct conetent
            FunkyHistory.loadNewContent(settings.target, location.href, settings.selector);
        });             
    }

    // Bind to click of tags            
    FunkyHistory.bindClicks = function(){

        jQuery(document).on('click', FunkyHistory.selector, function(e){
            e.preventDefault();

            // Cahce the clicked elements "this"
            FunkyHistory.clickedEl = this;

            // Set State to history
            var stateObj = { 
                selector: settings.selector,
                url: jQuery(this).attr('href')
            };                  
            history.pushState(stateObj, null, stateObj.url);
            FunkyHistory.loadNewContent( settings.target, stateObj.url, settings.selector );
        });
    }

    // Do stuff
    FunkyHistory.bindPopState();
    FunkyHistory.bindClicks();      

    // Return tags to be chainable
    return this;

};
 })( jQuery, window, document );

And you'd call it like this:

jQuery('#menu a').FunkyHistory({
    target: '#content', // This is replaced by AJAX content
    selector: "#content.new" // This is what to look for in the AJAX content
}, function(data){
    // Callback in here
    console.log(this, data);
});

I have a working example of it here.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.