Creating Ajax Based Website Using Javascript And CSS

We all know the many advantages of using AJAX for given tasks: users don't need to wait for a new page load, actions are performed in the background, and we can provide a much more dynamic user experience. The ideas are simple but the execution of AJAX-heavy web application creation can be very difficult. I createdmy blog as an AJAX-powered platform and I have some tips to share from my experience. Hopefully I can save you some trouble in the future!

Use Event Delegation

The basic key to AJAX-powered sites is using event delegation. Since you should never assume a given element exists in the page (...because it may have been brought in via AJAX), you should never try to directly assign event listeners to elements (other than the document.body). Instead, the best course of action is to use event delegation. Here's a very basic example of how you'd use event delegation with jQuery:
// Add event listener to the body because it is a constant
jQuery("body").on("click", "a", function(event) {
    event.preventDefault();

    //  Trigger the XHR to load the page content
    // ...

    //  Update the History with pushState
    // ...

    //  Other tasks
    // ...

});
During the creation of my site, I coded my JavaScript as though no element other than the <body> existed. As a result, it took me less than 30 minutes to implement AJAX page navigation. Event delegation makes AJAX page loads possible.

Use Pub/Sub to Signal Events

Event delegation signals when a link has been clicked, but implementing a publish & subscribe system provides much more power to your app. If you aren't familiar with pub/sub, think of it in terms of how radios work: radio stations publish (music) without needing to know who is listening. Listeners can subscribe (listen) without having a relationship to the station.
I'll use an example from my site with regard to why and how you'd use pub/sub. For any given article, I will want to (1) load the popular social media widgets and (2) show a star rating widget so users can tell me how useful the post was. On a more static site, you'd simply execute code to create those widgets duringDomContentLoaded. On an AJAX-heavy site, however, we may need to execute this functionality several times so we'll need a signal for when the page changes and we'll need to recreate these widgets.
Here's how we'd use pub/sub to accomplish this scenario:
// In the method where we do the AJAX request for new page content....
jQuery.ajax({
    url: event.target.href
}).done(function(data) {
    // Place the content in the page
    // ...


    // Send a pub/sub signal that the page is ready so that widgets can be created
    publish("/page/loaded", data); // Arguments are the channel name and data
});

// ... Elsewhere, where the we set up the social widgets....
subscribe("/page/loaded", function(data) {
    // Set up the widgets!
    createSocialWidgets(data);

    // Fade in the widgets
    // ...
});

// ... Elsewhere, where the we set up the rating widgets....
subscribe("/page/loaded", function(data) {
    // Set up the widgets!
    createStarRatingWidget(data);

    // Fade in the widget
    // ...
});
What's great about pub/sub is that we get to keep our JavaScript modules decoupled from the AJAX piece, and we don't have to deal with massive callbacks. One publish call and we're letting any module subscribe and react to that event!

Use a Solid pushState Manager

AJAX-heavy sites don't simply want to load new content -- they should also reflect the new page URL using theHTML5 History API. David Walsh Blog, a MooTools-based site, uses Christoph Pojer's outstanding History plugin. A popular jQuery utility for history is pjax.
Ensuring the browser history stays in sync with the AJAX page loads is important so that users can refresh, bookmark, or share the current page URL accurately. Doing so also ensure the browser's back and forward mechanisms work properly!

Place a Notifier in a Consistent Location

One potential problem, confusing users because they don't see the browser's loading bar moving, can be nipped in the bud by placing a notifier (otherwise called a spinner) in a consistent location on the page. It's important that users are always aware of when processing is occurring, and this is most true when dynamically loading and rendering page content!

Cache Request Results by URL

With the web, you never want to make more requests than you need to, and that's especially true when you're making full page requests. Creating a caching system for an AJAX-powered site is (usually) much simpler than you think:
var cache = {};

// ...
// ... within the AJAX callback
cache[url] = data;

// ...
// ... within the click callback that would set forth a request
if(cache[url]) {
    // Explicitly call the callback, passing it the cached page data
    return successCallback(cache[url]);
}
else {
    // ... do all of the AJAX request and callback stuff
}
This cache will not only display once a link is clicked multiple times, but when the user triggers back and forward actions. Your server and users will thank you for the client side caching!

Know When Not to Use AJAX

Not every page should be loaded via AJAX, and it's important that developers can identify cases when AJAX would be problematic. In many cases, the results of form submissions shouldn't be cached or fetched dynamically. There may be scenarios where your infrastructure would suffer from AJAX page loads. If you can identify URLs which shouldn't be loaded via AJAX, you can modify your jQuery event delegation selector to accommodate for them:
jQuery("body").on("click", "a:not(href$='/some/page')", function(event) {

});
You can also add more logic within the event delegation callback to accommodate for more URLs; if the URL clicked is a match, you can forego the preventDefault() call and simply let the page load per normal.
When you plan ahead and code flexibly, creating an AJAX-powered website is probably easier than you think. Keep in mind the tips provided in this post and you're 80% done. Of course, you will find a few niggles specific to your site, but those will be minor in relation to the overall app. Happy AJAXing!