How to Ajaxify your website with Ajaxify and history.js

Ajaxify is a great gist over on github by balupton that allows you to load page changes in via AJAX with a nice fade effect. URL’s are also kept intact while browsing and using History.js, browser history is handled correctly.

It is very easy to install, however, aside from the the initial set up, there is not much documentation so I’m going to share some things that I discovered while setting up a couple of different sites.

The initial set up if offensively easy and is exactly the as described on the Gist page. You just need to include jQuery, jQuery ScrollTo, History.js and the Ajaxify gist:

<!-- jQuery --> 
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script> 
 
<!-- jQuery ScrollTo Plugin -->
<script defer src="http://balupton.github.com/jquery-scrollto/scripts/jquery.scrollto.min.js"></script>
 
<!-- History.js --> 
<script defer src="http://balupton.github.com/history.js/scripts/bundled/html4+html5/jquery.history.js"></script>
 
<!-- Ajaxify -->
<script defer src="http://gist.github.com/raw/854622/ajaxify-html5.js"></script>

This is all you need. If you take a look at this EXAMPLE, you will see that pages are already loading with AJAX.

Something quite annoying I have noticed though is that it also outputs the page title at the top of the page on page change. You can easily hide this in CSS with:

.document-title{display:none}

The page change here is using AJAX but the whole page fades in and out with a white haze which is fine, but if you have a site with a common layout – static nav and content area throughout – we can improve on it by specifying just the main content to be Ajaxified.

Looking in the code for the gist, you will notice this line:

       ......
       contentSelector = '#content,article:first,.article:first,.post:first',
       ......

Ajaxify looks for any elements matching these selectors and applies the effect just to them. So, using the above example, we can Ajaxify just the main content div by adding an id of “content” to it (you can also achieve this by structuring your page using the HTML5 elements “article” or “post”):

.....
<div class="mainContent" id="content">
  ......
</div>
.....

Now, when you look at this EXAMPLE, you can see that when you change pages, only the main content is switched – notice the URL and titles still change too. You are also able to navigate to either of the pages directly by entering their URL in the address bar and clicking the ‘back’ and ‘forward’ buttons in your browser takes you through your history correctly.

Sometimes, you will want to disable AJAX from a link. A common situation is with image lightboxes such as fancybox where ajaxyify will interfere with the plugin. You will have a link like so:

<a class="fancybox" href="image.jpg"><img src="thumb.jpg" alt="Image Title" /></a>

AJAX will automatically be applied to this link so you will need to disable it. In ajaxyify.html5.js there is this line watches links to ajaxify:

...
$this.find('a:internal:not(.no-ajaxy)').click(function(event){
...

From this selector, you can easily see that by adding the class no-ajaxy to a link you can get ajaxify to ignore it. Like so:

<a href="/link/" class="no-ajaxy">Click me</a>
<a class="fancybox no-ajaxy" href="image.jpg"><img src="thumb.jpg" alt="Image Title" /></a>

From the below lines, you will notice that Ajaxify triggers a ‘statechangecomplete’ event on page change:

...
completedEventName = 'statechangecomplete',
...
// Complete the change
$window.trigger(completedEventName);
...

You can listen for this event like so:

...
$(window).on('statechangecomplete', function(e, eventInfo){
//your code
})
...
Did you like this post? Why not subscribe?

40 thoughts on “How to Ajaxify your website with Ajaxify and history.js

  1. Hi,

    First of all, thanks a lot for the article and the demo, it’s really great. I was looking at the javascript in the Ajaxify file. Indeed I would like to create a fadeOut and fadeIn effect when I call the content. I’m newbie in JS and I don’t success to make it work correctly. How could we do this animation (for example with your demo)?

    Many thanks!

  2. Hey,

    First off, thank you! This is indeed neat. Doing a lot of stuff with the code(including fetching data from multiple div).

    Where I’m falling short!
    My contact form(php) has an “on submit” action that is designed for a browser that has Javascript(JS) disabled. Infact the entire site functions with JS disabled.

    I added the code below to prevent the action (mentioned above) from taking place:
    $(“#buttonToPostForm”).click(function(e) {
    //postForm();
    e.preventDefault();
    });

    The problem:
    If I load the contact form page directly, yay, the submit form action is disabled. However if I navigate to the contact form via the ajaxy script the submit button is not disabled.

    Tried:
    no-ajaxy

    Pl. help! Cannot seem to understand the reason for the weird behaviour!
    Btw the above snippet loads on ready function of JS.

    • I see the issue. This is happening because your jQuery, once it has loaded is not aware of any new elements pulled in via ajax. You just need to modify your jQuery slightly to use $.on like so:

      $(document).on(‘click’, ‘#buttonToPostForm’, function(e){
      e.preventDefault();
      })

      Should do the trick. Let me know if you get any issues :)

  3. Awesomesauce!
    Just needed to update from jQuery 1.6.2 to jQuery 1.7.2 to use the “on” feature!
    Back to testing :D
    Thank you!

  4. Great post, have anyone tried with the current menu highlighting feature included in the ajaxify-html5.js? As I’m having difficulty dealing with getting it work.

  5. Brilliant article, can’t believe that there isn’t an official one that lays it out as clearly as this does.

    One question you may be able to help with?

    I’m ajaxing everything on my site using the following…

    contentSelector = ‘#main’,

    But I have another div located outside of #main which is housing an mp3 player to prevent breaks in the music when new pages are loaded.
    This works perfectly but I have some internal text links contained in the non-ajaxed div that I would like to load via ajax (at the moment they are just reloading the entire page stopping the music).

    I’ve searched high and low and can’t seem to find an answer on how to achieve this. I’ve tried adding the div that holds the text to the contentSelector like this…

    contentSelector = ‘#main, #current-data’,

    But it just messes the entire site up as it attempts to load all of the new content into both divs.

    Have you got any suggestions on how I can achieve what I’m trying to do?

    Basically I need a reverse function of the “no-ajaxy” class, a “do-ajaxy” class.

    Many thanks for your help in advance.

    • You can use hidden links on your ajaxed div and trigger those links from the non ajaxed container using jQuery.click() .

      • Hi Andres,
        Can you elaborate a little more on using hidden links? I’m trying to achieve something similar for my site. I have a blog section and a portfolio section that I want to be able to ajaxify.
        Cheers,
        Mike

    • The likely cause is because jQuery only recognises what is initially loaded into the page. Say you had a selector ‘#foo’ on a page that is loaded in with AJAXify… as it wasn’t present on the initial document.ready, jQuery does not know it exists. You can get around this using $.on. If you have a ‘click’ event on ‘#foo’ you can change $(‘#foo’).click(function(){…}) to $(document).on(‘click’, ‘#foo’, function(){…}). That should do the trick :)

  6. Hi, I got a terrible problem with ajaxify plugin and other jqueries plugin. I don’t know if you could help me to fix it.

    I use horizontal isotope and another plugin that resize and cut images in home page content. When I click to go another page, the ajaxify Works perfect, but when I back home; the isotope plugin and any other jquery plugin i use stop and don’t work.

    Do you know if it’s posible to load jquery plugin when I back home again?

    Thanks

    • I will be more specific, I don’t know if it could be useful to help me.

      This is my code to call Horizontal Isotope:

      jQuery(document).ready(function(jQuery) {
      jQuery(‘#container’).isotope({
      layoutMode: ‘masonryHorizontal’,
      masonryHorizontal: {
      rowHeight: 1,
      }
      });

      And This is my code to call the resize and cut images jquerie:

      jQuery(function() {
      CenterCropImage();
      jQuery(window).resize(function() {
      CenterCropImage();
      });
      });

      Both are loaded at home-page perfect. When I go to another page the ajaxify Works good too, but when I back home-page jqueries don’t load again.

      I hope you could help me. Thanks again

      • you might have to add them to the template and then display: none when loading the other pages?

        I am not sure how you would handle switching between different templates if your side had a homepage layout, at subpage layout and a contact page layout all with jquery plugins on each content area…

        If anyone has managed to figure this out it would be nice to know.

        • Hi Charls,

          The issue you are experiencing will be because jQuery is only aware of elements in the DOM when the document is first made ready ($(document).ready()). When you do a page change, the new elements are pulled in with AJAX and so jQuery doesn’t know they exist. You just need to fire isotop and crop image once the new elements have loaded in.

          Cheers

          • Thanks for answer Fraser, I don’t know if you could help me to do what you say, please.

            How can I do it?

          • does that mean you would move the piece of code that initiates the isotop plugin into the content area?

            and you wouldn’t wrap it in a $(document).ready()

          • You’d probably want to put this into the anonymous function on the statechangecomplete event (see the last part of the post). Code in here is fired every time a page change is made with ajaxify. If it was just sat in a document.ready function it would only fire when the page was first loaded or refreshed. Putting it in the statechangecomplete function ensures that it can be applied to newly injected elements.

          • Do you know how to make it update the active link in the navigation? been placing a class named active on every possible dom but nothing :O hehe

  7. Hi, thanks for the article — I have learned a lot. I hope you can help me with a little problem I have trying to make this work with this page:

    http://html5demos.com/history

    The problem is that if you also load ajaxify-html5.js, then the demo breaks (i.e., clicking on the link will redirect you). If you remove ajaxify-html5.js, then everything works fine — it seems like ajaxify-html5.js is conflicting with event.preventDefault().

    Has anyone gotten ajaxify-html5.js to work with normal href links like in the demo?

  8. Hi Thanks for this tutorial, really helpful and I managed to get this working for when I need a website that ajaxifys everything below the header. What I need is to only ajaxify certain divs on certain pages when I click on certain links.

    For instance I have a page that has a large sub menu with three options on it. For this page I would like to have the content below this menu reload for there three menus but not when I click the options on the main menu.

    Another example would be when I click on links to product category pages on the main shop page and have the main shop div reload but nothing else.

    Is this possible with the ajaxify plugin?

    Thanks again for the support

  9. Hey
    Is there a way i can make ajaxify work if i change url with jquery or javascript rather than html anchor tag?
    I have places in my code where dynamic links are generated with jquery and i want to ajaxify them all.

  10. I’ve been searching all over for a simple step-step Axaxify guide, and this post is by far the best basic tutorial out there. I tried to recreate your example site, but I must be missing something very important. Everything seems to works, even the back/forward buttons…but I can’t paste the urls into the browser to navigate to the pages directly.

    If possible, please let me know what I’m missing.
    testing.petercg.com

    Thank you!

    • I see the issue here. You need to include all your header/footer/etc in each of the pages. Ajaxify is designed to be a nice enhancement to browsers that support it. If the user is on an older browser, they should be able to just navigate from page to page as usual.

      When you click an ajaxified link, the default link action is prevented (if the browser supports it) and the requested page is retrieved with ajax. Ajaxify then strips just the main content from the retrieved page (ignoring the header/footer/etc) and swaps out the main content of the current page with that of the one it has just retrieved. Finally the URL is updated. You are left with the header/footer/etc of the original page and the content of the new page.

      Currently, when you navigate directly to page2.html for example, this is just loaded in to the browser in the convential way and has no reference to Ajaxify.

      Hope this helps. Let me know if you get any further issues.

      Cheers

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>