jQuery.LazyJaxDavis

Setup

Here's how to setup jQuery.LazyJaxDavis.

Load dependencies

First, load jQuery 1.8.2 (or later), Davis.js and jquery.lazyjaxdavis.js.

Call new $.LazyJaxDavis()

Then, call new $.LazyJaxDavis() with initializer as the 1st argument like below.

new $.LazyJaxDavis(function(router){

    // setup jQuery.LazyJaxDavis here
    
});

You can setup jQuery.LazyJaxDavis in this scope. In this page, I write about what you should do here. Before using jQuery.LazyJaxDavis, make sure that the comments are in the html. Those are what I wrote in introduction.

<body>
  blah blah blah
  <div id="content">
  <!-- LazyJaxDavis start -->
    Here's the maincontent!
  <!-- LazyJaxDavis end -->
  </div>
  blah blah blah
</body>

everyfetchsuccess event

jQuery.LazyJaxDavis hijacks all links in the page.
The first thing you need to do is - event bindings.

Instead of location change, jQuery.LazyJaxDavis fetches the target page. So, you need to define what to do after the ajax was successed.

new $.LazyJaxDavis(function(router){

  // bind ajax start event
  router.bind('everyfetchsuccess', function(page){

    // ripped new content
    var newcontent = page.rip('content');
    // update the page
    $('#content').html(newcontent);
    
    // tell the router that it's done (don't forget this!)
    page.trigger('pageready');

  });

});

With only these codes above, every links invokes ajaxed location change.

everyfetchstart event

If you like to show loading spinner or something while ajax was in progress, use everyfetchstart.

new $.LazyJaxDavis(function(router){

  var loading = new Loading; // here's my loading

  // bind ajax start event
  router.bind('everyfetchstart', function(page) {
    loading.show(); // show my loading
  });

  // bind ajax success event
  router.bind('everyfetchsuccess', function(page){
    loading.hide(); // hide my loading
    $('#content').html(page.rip('content'));
    page.trigger('pageready');
  });

});

The loading here is not what jQuery.LazyJaxDavis prepared. It's your code. everyfatchstart will be fired when page fetching ajax was satarted. You can tell users to know that it's loading with this.

everypageready event

When you finished refreshing the main content of the page, there must be something you need to do. For example, imagine rollover, tab, slider or something like that. Generally, you'll apply them like below.

$(function(){
  $('.apply-rollover').rollover(); // initialize my widget!
});

Oh hey, but newly added doms in the main content area are not ready for this. Because it was not in the page on documentready. It was added after ajax was successed. So, use everypageready event for this.

new $.LazyJaxDavis(function(router){

  var $content = $('#content'); // caching jQuery object is better

  router.bind('everyfetchstart', function(page) {
    loading.show();
  });
  router.bind('everyfetchsuccess', function(page){
    loading.hide();
    $content.html(page.rip('content'));
    page.trigger('pageready'); // don't forget this!
  });
  router.bind('everypageready', function(){
    $content.find('.apply-rollover').rollover(); // apply rollover within the main content
  });

});

With this, the rollover is ready for the newly added doms too.

This everypageready event will be fired when you call $.LazyJaxDavis() for the first time too. And this also fired when the browser did not support history API.

that is to say, this event works like the ready event for the refreshed content.

If you don't want to run everypageready on the first time, set firereadyonstart: false as option like below.

new $.LazyJaxDavis(function(router){

  // override default options
  router.option({
    firereadyonstart: false
  });
  
  everyfetchstart: function(page) {
    loading.show();
  },
  everyfetchsuccess: function(page){
    loading.hide();
    $('#content').html(page.rip('content'));
    page.trigger('pageready'); // don't forget this!
  },
  everypageready: function(){
    $('#content .apply-rollover').rollover();
  }

});

everyfetchfail event

If the page fetching ajax was failed, the visitor can't know that it was bugged. Because with the code above, there must be a loading indicator or something which tells it's still loading. To avoid this, use everyfetchfail event. This will be fired when ajax was failed.

new $.LazyJaxDavis(function(router){

  router.bind('everyfetchstart', function(page) {
    loading.show();
  });
  router.bind('everyfetchsuccess', function(page){
    loading.hide();
    $('#content').html(page.rip('content'));
    page.trigger('pageready'); // don't forget this!
  });

  // bind ajax fail event
  router.bind('everyfetchfail', function(){
    alert('got troubled!!!');
  });

});

The code above shows just a alert dialog. I think you should redirect to the 404 page or show something which tells the user that your website got troubled.

Click the link below to confirm how this works.

everyfetchabort event

This event will be fired when any ajax which is handled by jQuery.LazyJaxDavis was aborted. If 2nd page fetching request was started, jQuery.LazyJaxDavis makes 1st abort if there was already an ajax request with in progress status. It is pretty rare to use this event for something. So, basically don't take care of this event.

other options

The options listed below are also available.
And these are default value of each options. If you specify some, $.LazyJaxDavis will be initialized with the overridden options.

new $.LazyJaxDavis(function(router){

  router.option({
    ajaxoptions: {
      dataType: 'text',
      cache: true,
      type: 'GET'
    },
    expr: {
      title: /<title[^>]*>([^<]*)<\/title>/,
      content: /<!-- LazyJaxDavis start -->([\s\S]*)<!-- LazyJaxDavis end -->/
    },
    davis: {
      linkSelector: 'a:not([href^=#]):not(.apply-nolazy)',
      formSelector: 'form:not(.apply-nolazy)',
      throwErrors: false,
      handleRouteNotFound: true
    },
    minwaittime: 0,
    updatetitle: true,
    firereadyonstart: true,
    ignoregetvals: false
  });

});

ajaxoptions

Page fetching $.ajax options.
cahce: false may be preferred sometimes.

expr

Page ripping regexp patterns.
If you use page.rip('content') to rip the new content in everyfetchsuccess handler, jQuery.LazyJaxDavis rips the fetched html with expr.content. You can change this pattern. expr.title is to fetch the new page's title. So, don't change expr.title generally.

In addition, you may want to rip the other html source of the fetched page. Then define your own pattern like below. Then page.rip('sidenav') is also available.

new $.LazyJaxDavis(function(router){
  router.option({
    expr: {
      sidenav: /<!-- sidenav start -->([\s\S]*)<!-- sidenav end -->/
    }
  });
  router.bind('everyfetchsuccess', function(page){
    $('#content').html(page.rip('content'));
    $('#sidenav').html(page.rip('sidenav')); // this rips the sidenav
    page.trigger('pageready');
  });
});

I made a demo for this feature. Check the demo below to learn more.

You can also rip all matched regexp result with ripAll like below.

new $.LazyJaxDavis(function(router){
  router.option({
    expr: {
      imgsrc: /src="([^"]+)"/gi
    }
  });
  router.bind('everyfetchsuccess', function(page){
    console.log(page.ripAll('imgsrc')); // [ 'foobar.gif', 'moomoo.png', ... ]
    ...
  });
});

I created this ripAll feature for imgs' preloading. See the demo below to learn more.

davis

Davis.js options which jQuery.LazyJaxDavis uses.
About linkSelector and formSelector, check the Lazy links/forms in this document. About other options here, See Davis.js's document for more info. But, don't change handleRouteNotFound to false. jQuery.LazyJaxDavis uses this internally.

In addition, you can choose to set false to use jQuery.LazyJaxDavis without Davis.js. If you did so, jQuery.LazyJaxDavis works like just a URL router. To learn more, Check the demo below.

minwaittime

Minimum wait time to make ajax complete.
If you want to show something for loading, ajax may be completed before the loading spinner or something was revealed. Imagine full-Flash websites. They always show the loading indicator before the content was started. In such case, define milli seconds here. I made a demo for this too. Check the demo below to learn more. 0 as default.

updatetitle

Update document.title after page fetching or not.
This uses title regexp pattern I wrote above. You can set false to disable this feature. true as default.

firereadyonstart

Fires everypageready event on startup or not.
You can set false to disable this feature. You may turn off this If you apply rollover or something to the whole document on documentready. true as default.

ignoregetvals

Ignore all get values in URL like ?foo=bar or not.
This may be useful if your URL routings got troubled with annoying access analysis URL. Set true to turn on this. false as default.

Fork me on GitHub