Pure JavaScript ajax. Imagine a world without jQuery

Quick tip: XMLHttpRequest() is the one that does the magic!

Full story

I want to be clear from the beginning, all the javascript libraries out there are cool and useful, but do we always need them?

Since jQuery came out it helped lots of developers to speed up their job and create nicer and more interactive applications with ease. JQuery creator John Resig and has done such a good job that there are people thinking that there is some kind of magic behind it.

And one of the bigger jQuery magic seems to be the easy way it allows to handle ajax call, but here is a question: is it possible to make an ajax call in pure javascript? “Of course it is!” — Someone of you would say right now — “where do you think jQuery comes from?”. But many developers think it’s better to include an external library than write an ajax call in javascript from scratch because ti might bee too complicated.

I want to reveal to those of you how easy it is with a basic yet practical example.

In practice

Before giving the complete example let’s concentrate on the ajax call. The few lines that follow aim to make a GET ajax request, monitor it’s status and do something with the result of the request.

// instantiate a new request
var request = new XMLHttpRequest();

// before actually doing the request we need
// to define some actions to perform depending
// on the status of the request.
// the XMLHttpRequest object has a built in event
// called 'onreadystatechange' that will fire
// each time the status changed
request.onreadystatechange = function() {
if(request.readyState < 4) {
// handle preload
return;
}
if(request.status !== 200) {
// handle error
return;
}
if(request.readyState === 4) {
// handle successful request
// place here a callback function to perform
// some action with the request result
successCallback();
                }
};

// open the request to the specified source
request.open('GET', source, true);

// execute the request
request.send('');
// example of a success callback
successCallback = function() {
// on success place response content in the specified container
document.getElementById(container).innerHTML = request.responseText;

}

If you want to see an application of the code above just continue reading.

Let’s say we simply want to open every link of our website with ajax. This is out basic index.php file. Yes, I’m going to mix it with basic php to make it more realistic.

<!DOCTYPE html>
<html>
<head>
<title>Sample page</title>
<meta charset="UTF-8">
<!-- include the javascript that will load ajax content -->
<script type="text/javascript" src="ajax_loader.js"></script>
</head>
<body>

<h1>Some static content</h1>
<a href="?main_content=external_content.php">
Link to load dynamic content
</a>
<div id="main_content">
<!--
Here is where your dynamic content will be loaded.

You can have as many dynamic container as you like.

In my basic example you can attach one link to a
single container but you can implement a more
complete solution to handle multiple containers
at the same time
-->

<!-- Leave this empty for the moment... some php will follow -->
</div>
</body>
</html>

Now let’s see the little magic XMLHttpRequest in action inside our ajax_loader.js file

window.onload = function() {

var load = function(e) {
// prevent browser to open link
event.preventDefault();

// exit if target is undefined
if(typeof(e.target) == 'undefined' ) {return;}

// exit if clicked element is not a link
if (e.target.tagName !== 'A') {return;}

// get href from clicked element
var href = e.target.getAttribute("href");

// retrieve container and source
var href_parts = href.split('=');
var container = href_parts[0].substr(1);
var source = href_parts[1];

// instantiate a new request
var request = new XMLHttpRequest();

// bind a function to handle request status
request.onreadystatechange = function() {
if(request.readyState < 4) {
// handle preload
return;
}
if(request.status !== 200) {
// handle error
return;
}
if(request.readyState === 4) {
// handle successful request
successCallback();
}
};

// open the request to the specified source
request.open('GET', source, true);
// execute the request
request.send('');

successCallback = function() {
// on success place response content in the specified container
document.getElementById(container).innerHTML = request.responseText;

// change url in the address bar and save it in the history
history.pushState('','',"?"+container+"="+source);
}
};

// add an event listener to the entire document.
document.addEventListener('click', load, false);
// the reason why the event listener is attached
// to the whole document and not only to the <a>
// elements in the page is that otherwise the links
// included in the dynamic content would not
// liste to the click event

};

now let’s give a look back to some specific elements of our html

As said before the sample script will attach the behavior to any link, you only need to format it so to be read properly by the load() function. The format is “?container_name=filename.php”. Where container_name is the id of the div in which you want the content to be loaded in, while filename.php is the name of the file to be called by ajax to retrieve the content.

So if you have some content in your ‘external_content.php’ file and want it loaded in the div with id ‘main_content’ here is what you do

<a href="?main_content=external_content.php">Your link</a>
<div id="main_content"></div>

In this example the div ‘main_content’ is empty when the page first loads and will be populated on click of your link with the content of the external_content.php file.

At the same time the address bar of your browser will change from http://www.example.com/index.php tohttp://www.example.com/index.php?main_content=external_content.php and this new url will be registered in your browser history (thanks to the history.pushState() method).

Now let’s go further and see how we can make this SEO friendly so that http://www.example.com/index.php?main_content=external_content.php is a real address and the ‘main_content’ div is not empty when we load the page.

We can just add some php code to handle this. (Please not that you could even write some javascript to to a similar job)

<a href="?main_content=external_content.php">Load</a>
<div id="main_content">
<?php dynamicLoad('main_content','default_main_content.php'); ?>
</div>

Before showing it I want to explain what the php function dynamicLoad() does. It takes two parameters, the first is equivalent to the container id, the second if the file where the default content is. To be more clear, if the requested url is http://www.example.com/ the function will put the content of default_main_content.php in the main_content div but if the url requested by the browser ishttp://www.example.com/index.php?main_content=external_content.php then function will put the content of external_content.php in the main_content div.

This mechanism helps the page to be SEO friendly and user friendly, so when the search engine crawler will follow the href “?main_content=external_content.php” that brings to the url “http://www.example.com/index.php?main_content=external_content.php" will find the same content displayed dynamically with the ajax call. And this is also true for the user who will reload the page with a refresh or from the history.

Here is the simple dynamicLoad() php function

<?php
function dynamicLoad($contaner,$defaultSource){
$loadSource = $defaultSource;
if(isset($_GET[$contaner])) {
$loadSource = $_GET[$contaner];
}
include($loadSource);
}
?>

All the code above is not ready for production, it’s just a demonstration of hot to replace on of the most common jquery functionalities with pure javascript.

Like what you read? Give Igor Stimoli a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.