Life / Computer projects / Computer science

Adding site-wide Ajax to WordPress yourself

Browsing a site that uses AJAX throughout feels different: you can move between pages without seeing the browser refresh. If the site is fast enough, clicking a link feels smooth and instantaneous, with a polished touch.

I've now seen many WordPress sites use AJAX throughout with good results, so I also added AJAX code for partial page refreshes throughout the lipop theme.

Site-wide AJAX may sound technically complicated, but it's actually very easy to implement, because someone has already written the necessary functions. Any developer can easily adapt their website with just a few parameter changes.

This site-wide AJAX code was extracted from a WordPress plugin by Luke and Williams from the UK. It has a very broad range of uses: not only WordPress sites, but any website with a complete, consistent structure can use it. The conversion takes just a few simple steps.

The AJAX code:

var ajaxhome='';
var ajaxcontent = 'content';
var ajaxsearch_class = 'searchform';
var ajaxignore_string = new String('#, /wp-, .pdf, .zip, .rar, /goto');
var ajaxignore = ajaxignore_string.split(', ');
var ajaxloading_code = 'loading';
var ajaxloading_error_code = 'error';
var ajaxreloadDocumentReady = false;
var ajaxtrack_analytics = false
var ajaxscroll_top = true
var ajaxisLoad = false;
var ajaxstarted = false;
var ajaxsearchPath = null;
var ajaxua = jQuery.browser;
jQuery(document).ready(function() {
    ajaxloadPageInit("");
});
window.onpopstate = function(event) {
    if (ajaxstarted === true && ajaxcheck_ignore(document.location.toString()) == true) {
        ajaxloadPage(document.location.toString(),1);
    }
};
function ajaxloadPageInit(scope){
    jQuery(scope + "a").click(function(event){
        if (this.href.indexOf(ajaxhome) >= 0 && ajaxcheck_ignore(this.href) == true){
            event.preventDefault();
            this.blur();
            var caption = this.title  this.name  "";
            var group = this.rel  false;
            try {
                ajaxclick_code(this);
            } catch(err) {
            }
            ajaxloadPage(this.href);
        }
    });
    jQuery('.' + ajaxsearch_class).each(function(index) {
        if (jQuery(this).attr("action")) {
            ajaxsearchPath = jQuery(this).attr("action");;
            jQuery(this).submit(function() {
                submitSearch(jQuery(this).serialize());
                return false;
            });
        }
    });
    if (jQuery('.' + ajaxsearch_class).attr("action")) {} else {
    }
}
function ajaxloadPage(url, push, getData){
    if (!ajaxisLoad){
        if (ajaxscroll_top == true) {
            jQuery('html,body').animate({scrollTop: 0}, 1500);
        }
        ajaxisLoad = true;
        ajaxstarted = true;
        nohttp = url.replace("http://","").replace("https://","");
        firstsla = nohttp.indexOf("/");
        pathpos = url.indexOf(nohttp);
        path = url.substring(pathpos + firstsla);
        if (push != 1) {
            if (typeof window.history.pushState == "function") {
                var stateObj = { foo: 1000 + Math.random()*1001 };
                history.pushState(stateObj, "ajax page loaded...", path);
            } else {
            }
        }
        if (!jQuery('#' + ajaxcontent)) {
        }
        jQuery('#' + ajaxcontent).append(ajaxloading_code);
        jQuery('#' + ajaxcontent).fadeTo("slow", 0.4,function() {
            jQuery('#' + ajaxcontent).fadeIn("slow", function() {
                jQuery.ajax({
                    type: "GET",
                    url: url,
                    data: getData,
                    cache: false,
                    dataType: "html",
                    success: function(data) {
                        ajaxisLoad = false;
                        datax = data.split('<title>');
                        titlesx = data.split('</title>');
                        if (datax.length == 2  titlesx.length == 2) {
                            data = data.split('<title>')[1];
                            titles = data.split('</title>')[0];
                            jQuery(document).attr('title', (jQuery("<div/>").html(titles).text()));
                        } else {
                        }
                        if (ajaxtrack_analytics == true) {
                            if(typeof _gaq != "undefined") {
                                if (typeof getData == "undefined") {
                                    getData = "";
                                } else {
                                    getData = "?" + getData;
                                }
                                _gaq.push(['_trackPageview', path + getData]);
                            }
                        }
                        data = data.split('id="' + ajaxcontent + '"')[1];
                        data = data.substring(data.indexOf('>') + 1);
                        var depth = 1;
                        var output = '';
                        while(depth > 0) {
                            temp = data.split('</div>')[0];
                            i = 0;
                            pos = temp.indexOf("<div");
                            while (pos != -1) {
                                i++;
                                pos = temp.indexOf("<div", pos + 1);
                            }
                            depth=depth+i-1;
                            output=output+data.split('</div>')[0] + '</div>';
                            data = data.substring(data.indexOf('</div>') + 6);
                        }
                        document.getElementById(ajaxcontent).innerHTML = output;
                        jQuery('#' + ajaxcontent).css("position", "absolute");
                        jQuery('#' + ajaxcontent).css("left", "20000px");
                        jQuery('#' + ajaxcontent).show();
                        ajaxloadPageInit("#" + ajaxcontent + " ");
                        if (ajaxreloadDocumentReady == true) {
                            jQuery(document).trigger("ready");
                        }
                        try {
                            ajaxreload_code();
                        } catch(err) {
                        }
                        jQuery('#' + ajaxcontent).hide();
                        jQuery('#' + ajaxcontent).css("position", "");
                        jQuery('#' + ajaxcontent).css("left", "");
                        jQuery('#' + ajaxcontent).fadeTo("slow", 1, function() {});
                    },
                    error: function(jqXHR, textStatus, errorThrown) {
                        ajaxisLoad = false;
                        document.title = "Error loading requested page!";
                        document.getElementById(ajaxcontent).innerHTML = ajaxloading_error_code;
                    }
                });
            });
        });
    }
}
function submitSearch(param){
    if (!ajaxisLoad){
        ajaxloadPage(ajaxsearchPath, 0, param);
    }
}
function ajaxcheck_ignore(url) {
    for (var i in ajaxignore) {
        if (url.indexOf(ajaxignore[i]) >= 0) {
            return false;
        }
    }
    return true;
}
function ajaxreload_code() {
    //add code here   
}
function ajaxclick_code(thiss) {
    jQuery('ul.nav li').each(function() {
        jQuery(this).removeClass('current-menu-item');
    });
    jQuery(thiss).parents('li').addClass('current-menu-item');
}

A few parts of the code need to be adjusted for your site:

  1. On the first line, set ajaxhome to your website's URL.

  2. On the second line, set ajaxcontent to the ID of the container holding your site's articles—the part to load asynchronously.

  3. On the third line, set ajaxsearch_class to the name of the search-box container, usually “searchform”.

  4. On the fourth line, ajaxignore_string specifies links that should not use AJAX loading, such as feeds.

  5. On the sixth line, ajaxloading_code is the content shown during loading; it can include an animation.

  6. On the seventh line, ajaxloading_error_code is the content shown if loading fails; it can also include an animation. Once you have adjusted the code as described, save it as a separate JS file and include it in your page. The effect is immediate. Pretty magical, isn't it?  


AJAX Asynchronous Loading Affects Other jQuery Effects:

After adding the AJAX asynchronous loading code, a problem appears: all the jQuery animations work normally when you first open the site, but after following a link that triggers AJAX loading, all the animations stop working. This happens because the jQuery code can no longer find the elements after asynchronous loading, so the effects naturally disappear. To fix this, the jQuery code also needs to be modified. The solution is to use the live() event. Here is how to use the live() event:

$(selector).live(event,data,function)

Replace event with an action such as click() or hover(). data is an optional parameter, and function is the action to execute.

For example, to rewrite a click() event as a live() event, the original code looks like this:

$(".menu-item").click(function(){$(".topmenu").fadeOut(500)});

After the change:

$(".menu-item").live("click",function(){$(".topmenu").fadeOut(500)});

Further reading: Adding Ajax to selected WordPress pages yourself

Sources and credits

Type: Adapted

Original: The archived post did not provide a specific article URL.

Author or publisher: Tang Ye's Blog.

Note: The source credit above was retained from the archived post. This update repairs formatting; the exact original article has not been verified.

Published 05/21/2018 · Krunk Zhou

Join the conversation