5

I recently found this gist on how to Ajaxify a Website with the HTML5 History API using History.js, jQuery and ScrollTo: https://github.com/browserstate/ajaxify

I am having a hard time getting a simple version of this working and am not sure I understand everything. First, I loaded all the scripts provided in the gist, then set up a really simple nav and content section:

 <ul id="nav">
    <li id="home-link"><a href="/" title="Home">Home</a>/</li>
    <li id="work-link"><a href="/work" title="Work">Work</a>/</li>
    <li id="labs-link"><a href="/labs" title="Labs">Labs</a>/</li>
    <li id="blog-link"><a href="/blog" title="Blog">Blog</a>/</li>
    <li id="contact-link"><a href="/contact" title="Contact">Contact</a></li>
</ul>

<div id="content"></div>

Next, I changed the selector variables to match the html:

/* Application Specific Variables */
contentSelector = '#content',
$content = $(contentSelector),
contentNode = $content.get(0),
$menu = $('#nav'),
activeClass = 'active',
activeSelector = '.active',
menuChildrenSelector = 'li',

What I'm supposed to do next is where I get lost. All I want to do is load in html content specific to the nav link selected. So if I clicked "Work", I would like to load a work.html file into the content section and change the url to "mywebsite.com/work". To keep things easy lets say work.html and all other ajaxable content is located in the same directory.

Any help is greatly appreciated! Cheers!

balupton
  • 47,113
  • 32
  • 131
  • 182
eivers88
  • 6,207
  • 1
  • 33
  • 34

2 Answers2

7

So here is a real bare bones example of how I ended up ajaxifying the website I was working on that inspired this question. Sorry for the really long delay. First the HTML:

    <ul id="nav">
        <li id="home-link"><a href="home" class="ajaxify" title="Home">Home</a></li>
        <li id="work-link"><a href="work" class="ajaxify" title="Work">Work</a></li>
        <li id="labs-link"><a href="labs" class="ajaxify" title="Labs">Labs</a></li>
        <li id="blog-link"><a href="blog" class="ajaxify" title="Blog">Blog</a></li>
    </ul>

    <div id="content">Home Content</div>

Next the Javascript:

 <script type="text/javascript">

    var directory = 'content/'; //directory of the content we want to ajax in
    var state = History.getState();

    //for when they click on an ajax link
    $('.ajaxify').on('click', function(e){
        var $this = $(this);
        var href = $this.attr('href'); // use the href value to determine what content to ajax in
        $.ajax({
            url: directory + href + '.html', // create the necessary path for our ajax request
            dataType: 'html',
            success: function(data) {
                $('#content').html(data); // place our ajaxed content into our content area
                History.pushState(null,href, href + '.html'); // change the url and add our ajax request to our history
            }
        });
        e.preventDefault(); // we don't want the anchor tag to perform its native function
    });

    //for when they hit the back button
    $(window).on('statechange', function(){
        state = History.getState(); // find out what we previously ajaxed in
        $.ajax({
            url: directory + state.title + '.html', //create our path
            dataType: 'html',
            success: function(data) {
                $('#content').html(data);
            }
        });
    });
    </script>

Essentially all I am doing is intercepting anchor tag clicks with the class 'ajaxify' used to signal what specific content I want to load in. Once I intercept the click and determine what content to load, I then use history.js pushSate() to keep track of what order the user is going through the site and change the url without reloading the page. If they decide to hit the back button, the statechange listener will load in the correct content. If they decide to hit the refresh button, you will need to come up with a method of duplicating your index page with the different url names. This is easy to do in php or you could just copy, paste, and rename the index page as needed.

Here is an example I posted on Github: https://github.com/eivers88/ajaxify-simple-demo

Just a reminder, when working with ajax locally, it is best to run your projects on a personal web server like MAMP or WAMP. This demo will fail in chrome without a server running. However, it should work in firefox without a server.

eivers88
  • 6,207
  • 1
  • 33
  • 34
  • would you mind commenting each line of this? i've made several attempts to implement this over the years and never got it working - my current errors are related to 404's and basically the whole site format 'breaks' when clicking on a link. i've referenced the script sources `jquery-scrollto.js`, `jquery.history.js` and `ajaxify-html5.js` as shown on `https://github.com/browserstate/ajaxify` and copied and pasted your code above (my content area is `#main_content` and my files are in `/includes` directory) and added `ajaxify` class to links. i didn't install bookmarklet or chrome extension. – user1063287 Aug 17 '13 at 02:06
  • i ended up with results where a blank page would load, but if i looked at the source i could see the linked to page's content. so cannot implement at this stage. the only other anomaly was that i was using php, (ie header and footer on index page etc) not sure if that would effect the outcome. – user1063287 Aug 17 '13 at 03:12
  • @user1063287 I posted an example on github (see answer update), hopefully this will help some. I recommend getting a simple static html version running first before implementing php. – eivers88 Aug 17 '13 at 07:51
  • 1
    i have download the zip file and opened index.html in chrome (version 28.0.1500.95 m) and clicking on the menu links has no effect (no pages are loaded in an ajax style or otherwise). when i open index.html in firefox (23.0.1), the links and functionality does work. – user1063287 Aug 17 '13 at 11:14
  • 1
    Sorry but maybe I should have mentioned this, when working with ajax, it is best to run your projects using a personal web server like MAMP or WAMP. In chrome, ajax will not work at all without your site being run on a web server. However, If you try to open up index.html with firefox it should work without running on a server running. – eivers88 Aug 17 '13 at 16:30
0

There are a variety of things you would need to do given those requirements. Here is a function you can use:

function doAjax(htmlpage){
$.ajax({
    url:"/"+htmlpage, 
    type: 'GET',
    success: function(data){
        $('#content').html(data)
    }
});
}

The the simplest way to hook this out would be to adjust your tags above to be like:

<a href="#" onclick="doAjax('work.html');return false;"><img></a>

It would however be slightly more "correct" (though functionally the same) to do this with jquery in a script tag at the top:

$(function () {
    $('#buttonid1').click(function(){doAjax('work.html')});
    $('#buttonid2').click(function(){doAjax('about.html')});
    $('#buttonid3').click(function(){doAjax('contact.html')});
});

Note in both cases, these "work.html" pages shouldn't be full html documents, they should just be what goes in your content div.

This ajax will do nothing to change the url that your visitor sees. To get that to work, you'll have to use the html5 history api. It is quite a bit more complicated than the the ajax request I have above. So if you don't have a full mastery of what I wrote above, it may or may not be appropriate.

Landon
  • 4,088
  • 3
  • 28
  • 42
  • Thanks Landon, I already understand how to use `$.ajax` by itself. I would really like to use the gist that I linked to above since it handles cross browser compatibility issues and degrades gracefully. I understand the importance of mastering the API behind the magic but in the short term I'd like to just get a simple website going that uses this gist. – eivers88 Sep 18 '12 at 23:12
  • ohh ok, good luck, and fyi, it is always helpful to post a link to a page that you're working on that shows what's you've tried so people can help identify what is wrong. – Landon Sep 18 '12 at 23:20