0

I’m developing a website based on this tutorial and would like to rename the URLs from /?chapter=# to their respective navigation names, e.g. /work, /about, /services etc.

index.php:

<aside id="menu">
    <div id="scroll">
        <nav>
            <ul>
                <li><a href="#introduction">Work</a></li>
                <li><a href="#chapter1">About</a></li>
                <li><a href="#chapter2">Services</a></li>
                <li>Blog <!-- Coming Soon... --> </li>
                <li><a href="#chapter4">Contact</a></li>
            </ul>
        </nav>
    </div> <!-- #scroll -->    
</aside> <!-- #menu -->

...

...

<div class="content-scroller">
    <div class="content-wrapper">
        <article class="content" id="introduction">
            <div class="inner">  
...
...
        <article class="content" id="chapter1">
            <div class="inner">  
...
...

jquery.page.js:

(function(window, undefined) {

    var Page    = (function() {

        var $container          = $( '#container' ),
            // the scroll container that wraps the articles
            $scroller           = $container.find( 'div.content-scroller' ),
            $menu               = $container.find( 'aside' ),
            // menu links
            $links              = $menu.find( 'a' ),
            $articles           = $container.find( 'div.content-wrapper > article' ),
            // button to scroll to the top of the chapter
            // only shown when screen size < 960
            $toTop              = $container.find( 'a.totop-link' ),
            // the browser nhistory object
            History             = window.History,
            // animation options
            animation           = { speed : 800, easing : 'easeInOutExpo' },
            // jScrollPane options
            scrollOptions       = { verticalGutter : 0, hideFocus : true },
            // init function
            init                = function() {

                // initialize the jScrollPane on both the menu and articles
                _initCustomScroll();
                // initialize some events
                _initEvents();
                // sets some css properties 
                _layout();
                // jumps to the respective chapter
                // according to the url
                _goto();

            },
            _initCustomScroll   = function() {

                // Only add custom scroll to articles if screen size > 960.
                // If not the articles will be expanded
                if( $(window).width() > 960 ) {

                    $articles.jScrollPane( scrollOptions );

                }
                // add custom scroll to menu
                $menu.children( '#scroll' ).jScrollPane( scrollOptions );

            },
            _goto               = function( chapter ) {

                    // get the url from history state (e.g. chapter=3) and extract the chapter number
                var chapter     = chapter || History.getState().url.queryStringToJSON().chapter,
                    isHome      = ( chapter === undefined ),
                    // we will jump to the introduction chapter if theres no chapter
                    $article    = $( chapter ? '#' + 'chapter' + chapter : '#' + 'introduction' );

                if( $article.length ) {

                        // left / top of the element
                    var left        = $article.position().left,
                        top         = $article.position().top,
                        // check if we are scrolling down or left
                        // is_v will be true when the screen size < 960
                        is_v        = ( $(document).height() - $(window).height() > 0 ),
                        // animation parameters:
                        // if vertically scrolling then the body will animate the scrollTop,
                        // otherwise the scroller (div.content-scroller) will animate the scrollLeft
                        param       = ( is_v ) ? { scrollTop : (isHome) ? top : top + $menu.outerHeight( true ) } : { scrollLeft : left },
                        $elScroller = ( is_v ) ? $( 'html, body' ) : $scroller;

                    $elScroller.stop().animate( param, animation.speed, animation.easing, function() {

                        // active class for selected chapter
                        $articles.removeClass( 'content-active' );
                        $article.addClass( 'content-active' );

                    } );

                }

            },
            _saveState          = function( chapter ) {

                // adds a new state to the history object
                // this will trigger the statechange on the window
                if( History.getState().url.queryStringToJSON().chapter !== chapter ) {

                    History.pushState( null, null, '?chapter=' + chapter );

                }

            },
            _layout             = function() {

                // control the overflow property of the scroller (div.content-scroller)
                var windowWidth = $(window).width();
                switch( true ) {

                    case ( windowWidth <= 960 ) : $scroller.scrollLeft( 0 ).css( 'overflow', 'visible' ); break;
                    case ( windowWidth <= 1024 ): $scroller.css( 'overflow-x', 'scroll' ); break;
                    case ( windowWidth > 1024 ) : $scroller.css( 'overflow', 'hidden' ); break;

                };

            },
            _initEvents         = function() {

                _initWindowEvents();
                _initMenuEvents();
                _initArticleEvents();

            },
            _initWindowEvents   = function() {

                $(window).on({
                    // when resizing the window we need to reinitialize or destroy the jScrollPanes
                    // depending on the screen size
                    'smartresize' : function( event ) {

                        _layout();

                        $('article.content').each( function() {

                            var $article    = $(this),
                                aJSP        = $article.data( 'jsp' );

                            if( $(window).width() > 960 ) {

                                ( aJSP === undefined ) ? $article.jScrollPane( scrollOptions ) : aJSP.reinitialise();

                                _initArticleEvents();

                            }   
                            else {

                                // destroy article's custom scroll if screen size <= 960px
                                if( aJSP !== undefined )
                                    aJSP.destroy();

                                $container.off( 'click', 'article.content' );

                            }

                        });

                        var nJSP = $menu.children( '#scroll' ).data( 'jsp' );
                        nJSP.reinitialise();

                        // jumps to the current chapter
                        _goto();

                    },
                    // triggered when the history state changes - jumps to the respective chapter
                    'statechange' : function( event ) {

                        _goto();

                    }
                });

            },
            _initMenuEvents     = function() {

                // when we click a menu link we check which chapter the link refers to,
                // and we save the state on the history obj.
                // the statechange of the window is then triggered and the page/scroller scrolls to the 
                // respective chapter's position
                $links.on( 'click', function( event ) {

                    var href        = $(this).attr('href'),
                        chapter     = ( href.search(/chapter/) !== -1 ) ? href.substring(8) : 0;

                    _saveState( chapter );

                    return false;

                });

                // scrolls to the top of the page.
                // this button will only be visible for screen size < 960
                $toTop.on( 'click', function( event ) {

                    $( 'html, body' ).stop().animate( { scrollTop : 0 }, animation.speed, animation.easing );

                    return false;

                });

            },
            _initArticleEvents  = function() {

                // when we click on an article we check which chapter the article refers to,
                // and we save the state on the history obj.
                // the statechange of the window is then triggered and the page/scroller scrolls to the 
                // respective chapter's position
                $container.on( 'click', 'article.content', function( event ) {

                    var id          = $(this).attr('id'),
                        chapter     = ( id.search(/chapter/) !== -1 ) ? id.substring(7) : 0;

                    _saveState( chapter );

            //      return false;

                });

            };

        return { init : init }; 

    })();

    Page.init();

})(window);

How would I be able to do this?

Thanks

3
  • Whats the issue you're having? Commented Oct 9, 2012 at 21:52
  • @Aakil Fernandes changing the URL from www.siteaddress.com/?chapter=1, www.siteaddress.com/?chapter=2 to www.siteaddress.com/about, www.siteaddress.com/services etc. Commented Oct 9, 2012 at 22:29
  • 1
    This should be done on the server side. Commented Oct 21, 2012 at 19:50

1 Answer 1

2

Well, this line is what's writing your history state:

 History.pushState(null, null, '?chapter=' + chapter);

So you would need to modify that function to do what you want. If you have a small site then you could make conditionals to swap the state to whatever you want easily. If you have a large dynamic site you don't want to do this unless you love horrible, tedious maintenance...

_saveState = function(chapter) {

    // adds a new state to the history object
    // this will trigger the statechange on the window
    if (History.getState().url.queryStringToJSON().chapter !== chapter) {
        var page;
        if(chapter == 1)
            page = "/about";
        else if(chapter == 2)
            page = "/services";
        else
            page = '?chapter=' + chapter;

        History.pushState(null, null, page);

    }
},

I may have missed the point of your question though. If so I can update this answer

Sign up to request clarification or add additional context in comments.

6 Comments

updated. I bet you just put the added page conditionals in the wrong place. if structure is if - else if - else if else ... makes sense?
in _goto try console.log(chapter) right before if($article.length) to see what it is reading. that function is cross referencing the history state chapter with html dom elements that have corresponding id's. That means an html id of chapter1 might need to be renamed to chapterAbout for this to work. Or you have to modify the js to match the expected conditions set in that history push state.
Fantastic work! I copy+pasted your solution into my jquery.page.js file and renamed the chapter1 and chapter2 in my index.php to chapterAbout and chapterServices. The functionality is working perfectly and the URL's now read: www.siteaddress.com/?chapter=About and www.siteaddress.com/?chapter=Services. Is there a further way to remove the ?chapter= part Kai? And once again, thank you for all your help.
That part is written in a conditional in my example. Supposing you used this code as is, you would have to replace the else conditional with whatever makes sense for your site. Your html does not set the ?chapter= part, your js does. So remove or replace that part and you should be good.
Thanks for getting back to me so soon Kai. I've removed the else page = '?chapter=' + chapter; line from the jquery.page.js file and left the index.php file alone as suggested, but no luck. Once I click on the links in the navigation, nothing happens.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.