Search code examples
jqueryurltabsbookmarks

Making jQuery bookmarkable (i.e - for a content slider)


I have made my own custom tabbed content script and it works great. The only thing missing is being able to book mark different sections.

I know the URL needs re-writing somehow. At the moment I am using preventDefault to stop the page refreshing, this also stops the URL from changing.

I have also tried manually re-writing the URL but nothing happens as I guess it needs some form of hooks to detect the entered URL.

Thanks in advance, Henry.

EDIT: Javascript: http://pastebin.com/1yhzxkUi HTML: http://pastebin.com/WH1CbRZJ


Solution

  • To store the history of a page, the most popular and full featured/supported way is using hashchanges. This means that say you go from yoursite/page.html#page1 to yoursite/page.html#page2 you can track that change, and because we are using hashes it can be picked up by bookmarks and back and forward buttons.

    You can find a great way to bind to hash changes using the jQuery History project http://www.balupton.com/projects/jquery-history

    There is also a full featured AJAX extension for it, allowing you to easily integrate Ajax requests to your states/hashes to transform your website into a full featured Web 2.0 Application: http://www.balupton.com/projects/jquery-ajaxy

    They both provide great documentation on their demo pages to explain what is happening and what is going on.

    Here is an example of using jQuery History (as taken from the demo site):

    // Bind a handler for ALL hash/state changes
    $.History.bind(function(state){
        // Update the current element to indicate which state we are now on
        $current.text('Our current state is: ['+state+']');
        // Update the page"s title with our current state on the end
        document.title = document_title + ' | ' + state;
    });
    
    // Bind a handler for state: apricots
    $.History.bind('/apricots',function(state){
        // Update Menu
        updateMenu(state);
        // Show apricots tab, hide the other tabs
        $tabs.hide();
        $apricots.stop(true,true).fadeIn(200);
    });
    

    And an example of jQuery Ajaxy (as taken from the demo site):

            'page': {
                selector: '.ajaxy-page',
                matches: /^\/pages\/?/,
                request: function(){
                    // Log what is happening
                    window.console.debug('$.Ajaxy.configure.Controllers.page.request', [this,arguments]);
                    // Adjust Menu
                    $menu.children('.active').removeClass('active');
                    // Hide Content
                    $content.stop(true,true).fadeOut(400);
                    // Return true
                    return true;
                },
                response: function(){
                    // Prepare
                    var Ajaxy = $.Ajaxy; var data = this.State.Response.data; var state = this.state;
                    // Log what is happening
                    window.console.debug('$.Ajaxy.configure.Controllers.page.response', [this,arguments], data, state);
                    // Adjust Menu
                    $menu.children(':has(a[href*="'+state+'"])').addClass('active').siblings('.active').removeClass('active');
                    // Show Content
                    var Action = this;
                    $content.html(data.content).fadeIn(400,function(){
                        Action.documentReady($content);
                    });
                    // Return true
                    return true;
    

    And if you ever want to get the querystring params (so yoursite/page.html#page1?a.b=1&a.c=2) you can just use:

    $.History.bind(function(state){
        var params = state.queryStringToJSON(); // would give you back {a:{b:1,c:2}}
    }
    

    So check out those demo links to see them in action, and for all installation and usage details.


    Edit: After seeing your code, this is all you would have to do to use it with jQuery History.

    Change:

    $('.tabbed_content .tabs li a').live('click',
        function (e){
            e.preventDefault();
            switchTab($(this));
        });
    

    To:

    // Bind a handler for ALL hash/state changes
    $.History.bind(function(state){
        switchTab(state);
    });
    

    Or if you plan to use jQuery History for other areas too, then we would want to ensure that we only call switchTab for our tabs and not all hashes:

    // Bind a handler for ALL hash/state changes
    $.History.bind(function(state){
        if ( $('.tabbed_content > .content > li[id='+state+']').length ) switchTab(state);
    });
    

    We no longer use a onclick event, instead we bind to jQuery History as that will detect the hashchange. This is the most important concept to understand, as for instance if we bookmark the site then go back to it, we never clicked it. So instead we change our clicks to bind to the hashchange. As when we click it, bookmark it, back or forward, the hashchange will always fire :-)