Loading a Random HTML Page Inline - Page 2

by kirupa  |  20 February 2011

  Have questions? Discuss this HTML / JavaScript tutorial with others on the forums.

Now that you have a working example from following along in the previous page, let's start to look at why everything works the way it does on this page.

Examining the Code
Let's start at the very top:

function loadExternalHTMLPage() {
var xmlhttp;
var pagesToDisplay = ['good.htm', 'evil.htm'];
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("contentArea").innerHTML = xmlhttp.responseText;
}
}
var randomnumber = Math.floor(Math.random() * pagesToDisplay.length);
xmlhttp.open("GET", pagesToDisplay[randomnumber], true);
xmlhttp.send();
}

This function is called loadExternalHTMLPage, and inside it, everything necessary to load your external HTML page lives.

In the first two lines, we are declaring two variables called xmlhttp and pagesToDisplay:

var xmlhttp;
var pagesToDisplay = ['good.htm', 'evil.htm'];

The xmlhttp variable is pretty boring right now. It is just declared so that we can reuse it again.

The pagesToDisplay variable stores an array of file paths that point to the HTML pages you wish to load. You can add or remove files from here as necessary, and one of these files will be randomly chosen for display later.


Next up is the code for creating our XMLHttpRequest object:

if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}

Notice that in both the true and false state of the if statement, your xmlhttp variable gets initialized. The first case is hit if you are running a browser more modern than Internet Explorer 7:

if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}

If you are running in Internet Explorer 5 or 6, the else case gets called:

if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}

In either case (ha!), you end up setting your xmlhttp variable to an object capable of handling the HTTP requests needed.


Next up, let's look at the function that gets called whenever a web request is made to load a new HTML page:

xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("contentArea").innerHTML = xmlhttp.responseText;
}
}

More specifically, this function is an event handler that gets called every time the onreadystatechange event gets fired. The onreadystatechange event gets called every time you interact with your XMLHttpRequest object.

The case we care about is when the request has been made / response is ready (readyState = 4), and the page we are loading exists (status = 200):

xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("contentArea").innerHTML = xmlhttp.responseText;
}
}

As long as those two conditions exist, all that is left is to load the response into the HTML element whose ID you specify as the argument to getElementById:

document.getElementById("contentArea").innerHTML = xmlhttp.responseText;

The response, stored by xmlhttp.responseText is the actual HTML of the page you are planning on loading. The ID of the element in our case is one that is called contentArea.

To summarize this function, when a valid request has been made, a response returned, and the page we want to load actually exists, we tell our browser to simply go ahead and download the HTML into the element you want to load the page into.


We are on a roll here taking about xmlhttp, so I am going to skip the next line temporarily before returning to it in a little bit.

Note that the earlier function doesn't fire automatically. The reason, like I mentioned earlier, is because onreadystatechange is an event handler whose event needs to be fired. The firing of that event happens indirectly by the following two lines of code where the actual request is defined and sent:

xmlhttp.open("GET", pagesToDisplay[randomnumber], true);
xmlhttp.send();

In the first line, we pass in a GET request and specify the URL of the HTML page we wish to load. The true argument is used to specify that you want this request to be made asynchronously. If you set this value as false, the request is made synchronously and your browser will block most operations until the page you request to load is fully loaded. In general, you should go with asynchronous unless you really have a good reason not to.

The second line is important despite its simplicity. It is this line that takes the request you created in open one line ago and passes it off. Once this request is sent off, your onreadystatechange event gets fired a few times as each part of your request moves through its paces. One of the times it fires is the one we are interested in and you saw described earlier (readyState = 4, status = 200), and when those states get hit, the page you specified as part of your open request gets loaded.


Ok, now let's go back to the one line I skipped earlier:

var randomnumber = Math.floor(Math.random() * pagesToDisplay.length);

What I am doing is trying to select a random HTML page from the array of HTML pages you declared earlier. The first step is to get the index position of a page in our array, and that is what this line does.

Once I have the index position, all that is left is to actually retrieve the value in the array it is pointing to:

xmlhttp.open("GET", pagesToDisplay[randomnumber], true);

And with this, you are done looking at the code that makes all of this work! You aren't done yet though. There are a few loose ends that need to be covered as well.

Paths Need to be Relative to the Target Page
If the page you are loading uses relative paths for content such as images, make sure that those paths are still valid when that page is loaded into its final destination. Once your page gets loaded, from your browser's eyes, it no longer has any interest in where it came. All paths are resolved based on where your target page currently is.

Bring your Styles with You
Non-inline styles will not travel with your HTML page when it gets loaded into the parent / target HTML page. Make sure that any styles that you wish to use are available in the page your loaded page will end up living in.

One solution is to manually copy any styles and paste it into your target page. Another solution is to have all of your styles defined in a stylesheet that you can import in your target page. While another solution is that you inline all of your styles, inlining styles is generally frowned upon by people who generally frown a lot, so don't do it unless you really have to.

Conclusion
Well, this wraps up this tutorial. I hope you found learning how to load a random HTML page quite useful. As you can guess, I am not much for inspirational conclusions. Go forth and multiply.

Just a final word before we wrap up. If you have a question and/or want to be part of a friendly, collaborative community of over 220k other developers like yourself, post on the forums for a quick response!

Kirupa's signature!


 1 | 2




SUPPORTERS:

kirupa.com's fast and reliable hosting provided by Media Temple.