Introduction
Are you just starting out using JavaScript to make web pages? Then this article is for you. (Otherwise it may be too basic.) What I want to do here is to go through the typical process of creating a web page focusing on using JavaScript in the browser. I will assume you have a basic knowledge of and understanding of how to make a web page and some experience with JavaScript and what the point of it is. Hopefully this will give you an idea of how you should approach the task of creating a single page web application from scratch. As you follow the example put the code into your own .html file and open it in a browser, preferably Chrome.
HTML
So let me jump right into it. Let’s say you need a web page starting from scratch, so you create a plain old .html file. Now what? Where do you start? Well you first have to have you standard HTML markup such as html
, head
, and body
tags. Well what else do you need? There’s a wide variety of markup you can include, what’s the best way to approach this. My stance is: why reinvent the wheel. What I like to do is use a template that has already been created for me called html5boiler plate. Basically a collection of very smart, experienced and knowledgeable people in the web industry put together that knowledge and experience to create a base template of how every web page should start out as. Go to the website www.html5boilerplate.com and get it. It’s a simple zip download. Once you open it the important part is the index.html.
<!DOCTYPE html>
<!--
<!--
<!--
<!-- <html class="no-js"> <!--
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<!--
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/main.css">
<script src="js/vendor/modernizr-2.6.2.min.js"></script>
</head>
<body>
<!--
<!--
<p>Hello world! This is HTML5 Boilerplate.</p>
<script src="http://www.codeproject.com/ajax.googleapis.com/
ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/' +
'vendor/jquery-1.9.1.min.js"><\/script>')</script>
<script src="js/plugins.js"></script>
<script src="js/main.js"></script>
<!--
<script>
var _gaq=[['_setAccount','UA-XXXXX-X'],['_trackPageview']];
(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];
g.src='http://www.codeproject.com/www.google-analytics.com/ga.js';
s.parentNode.insertBefore(g,s)}(document,'script'));
</script>
</body>
</html>
I’m not going to go into the specifics of what everything means. You probably don’t even need a majority of what is in here but let’s just ignore it for now. Let’s just take it for granted that this is how you should start off every web page you make.
DOM
One thing that is important to understand before taking on JavaScript is the concept of the Document Object Model. Simply put, this is the in memory representation of your HTML. If you have a html file with markup and you use JavaScript to change something to be a different color, well you aren't actually changing the HTML that is in your .html file, you are changing the things in memory that represent that HTML. So when you are thinking about how your web page is constructed imagine that there is one area that is its own separate space called the DOM where all the HTML has been pulled out of your .html file and put into memory. And then there is another totally separate space where your JavaScript lives. And these 2 separate areas interact with each other across some lines of communication.
JavaScript
Great, now we have the container for the JavaScript. So let’s get to the JavaScript. You can define your JavaScript in three ways, either in your HTML tags, directly inside the script tag, or you can put it into another file on your web server and have the script tag reference it, which then makes the browser down load the file and hand it to the JavaScript engine.
Lesson 1
It's best practice to put your JavaScript in an external file and reference it in the script tag.
This approach makes the code cleaner and also allows that file to be cached so it doesn’t have to be downloaded every time. So let’s do something. First I'm going to take a lot of the stuff out of html5boilerplate that we don't need. I’ll put in a script tag with a reference to a resource that takes 5 seconds to load. There is a reason I’m doing this and you’ll see why in a second. And we’ll put some text in there. Put this in your .html file and open in the browser.
<!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
</head>
<body>
<!--[if lt IE 7]>
<p class="chromeframe">You are using an <strong>outdated</strong>
browser. Please <a href="http://browsehappy.com/">upgrade your browser</a>
or <a href="http://www.google.com/chromeframe/?redirect=true">activate
Google Chrome Frame</a> to improve your experience.</p>
<![endif]-->
<!-- Add your site or application content here -->
<p>Hello world! This is HTML5 Boilerplate.</p>
<script src="http://deelay.me/5000?http://mysite.com/image.gif"></script>
Where am I?
</body>
</html>
You’ll notice the words from the html5boilerplate showed up, but our text didn't show up right away, why?
Lesson 2
In the browser, everything is processed in a top to bottom synchronous manner. The browser will not render html until it is done with what is above it, this includes JavaScript. And if your JavaScript file takes long time to get downloaded it will block the browser from rendering html to the user, this is not good. That is why its generally accepted best practice to put all script tags as low in the body tag as possible. So it would look like this:
<p>Hello world! This is HTML5 Boilerplate.</p>
Where am I?
<script src="http://deelay.me/5000?http://mysite.com/image.gif"></script>
Now with these changes you will see our text show up immediately even though the browser is still waiting on the script file to download. Super, now the user sees the interface as soon as possible. So now let's have JavaScript actually do something. I want to have a div tag and make it blue, whoa. So let's create some html as such:
<!DOCTYPE html>
<!--
<!--
<!--
<!-- <html class="no-js"> <!--
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
</head>
<body>
<!--
<!--
<p>Hello world! This is HTML5 Boilerplate.</p>
<script >
var div1 = document.getElementById("div1");
div1.style.backgroundColor= 'blue'
</script>
<div id="div1">I want to be blue.</div>
</body>
</html>
Load this into your browser and what do we get? It's not blue. Hmm, what happened? It didn't make it blue, why. This is further demonstrating the point I made earlier, everything is processing from top to bottom. We got a reference to div1
but at that point div1
didn't exist yet because the parser hasn't gotten to it to put it in the DOM. This brings me to an important point.
Lesson 3
For the most part JavaScript execution should start when the HTML is fully parsed and the DOM is done being created. Well, how do we do this? You might be thinking window.onload
of course. Not so fast. There is one slight issue with window.onload
. It is triggered when the DOM is completely ready including downloading images. In most cases we probably don’t care if images have downloaded yet and we want our JavaScript to execute as soon as possible. Some images could be large and would delay the JavaScript from doing what it needs to do. It may take two seconds to download an image several megs big perhaps. It would be nice if we could ignore that two seconds and just get the JavaScript going ASAP. How do we do this? In some browsers there is a built-in way to know when the DOM has been created not including images, but the issue is not all browsers have this. This is where jQuery can come into play.
So what is the point of this jQuery thing? One thing that is important to understand about the web environment is that there are many browsers out there, Chrome, Firefox, IE..., and also there are many versions of those individual browsers IE7, IE8, IE9, IE10, ..etc. Any person could be using any of them at any time. Theoretically these browsers are all supposed to work the same. If you write some JavaScript it should work the same in all browsers. But in reality this is far from true. jQuery is a collection of pre-made JavaScript code or what is called a library, whose purpose is to normalize the discrepancies in the way that different browsers work, as well as provide utility functionality. In other words, it will make sure that your code will work the same in all browsers, so you don’t have to worry about it. I would recommend you familiarize yourself with it and use it.
In this case, jQuery provides a way to notify your JavaScript code that the DOM is ready but not including image downloads and do this in all browsers reliably. So let's change our code to use this feature. Let's put back the reference to jQuery that we previously took out and then use the syntax to define a function that gets called as soon as the DOM is ready not including images.
<!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
</head>
<body>
<!--[if lt IE 7]>
<p class="chromeframe">You are using an <strong>outdated</strong> browser.
Please <a href="http://browsehappy.com/">upgrade your browser</a>
or <a href="http://www.google.com/chromeframe/?redirect=true">activate Google
Chrome Frame</a> to improve your experience.</p>
<![endif]-->
<!-- Add your site or application content here -->
<p>Hello world! This is HTML5 Boilerplate.</p>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script >
$(function(){
var div1 = document.getElementById("div1");
div1.style.backgroundColor= 'blue'
})
</script>
<div id="div1">I want to be blue.</div>
</body>
</html>
So here we are sending a function into the jQuery $
dollar sign function. When the DOM is ready the function that we sent in is called and since we have guaranteed that div1
exists before our code executes, we have blue.
Scope
Copy the following code and run it in your file.
<script >
var text = "hello";
</script>
<script >
alert(text)
</script>
We have two separate script
tags, one defines a variable text the other uses the variable and alerts it out. You should see "hello" pop up in a dialog box. So how does this work? How does the second script
tag know about the variable in the first tag? Where did the variable in the first tag go when it was created? You can think of it as such: even though there may be many script tags in the page, there is really only one script tag that holds everything. This is known as the global scope. So where did the variable go, it can't just be floating around in memory. In JavaScript there is one object in memory that holds all the references to all the variables created in the global scope. In the case of the browser the global object is the window object. Each browser will automatically have an object called "window
" when the page gets loaded. This is where our text variable now lives.
Let me deviate for a moment to point out a useful tool. Using Chrome and its included developer tools we have access to all JavaScript that has been loaded into memory space of the current page. It also allows us to manipulate in memory values and debug running code. Just hit F12 or right click anywhere on the page and choose inspect element. This is an invaluable resource when creating web applications.
So if we open the tools and go to the console, this will allow us to access JavaScript objects in the memory of the browser. Simply start typing and it brings up intellisense to tell you what all is in there.
Screen shot example
When you type "window" and then "." you will see a list of possible things in a drop down. One of them will be our variable "text". So if you type "window.text
" and hit Enter, you will see the console spit out "hello".
Lesson 4
It is generally accepted that having things "live" off of the global object (window) is bad.
Why? Well there is one interesting feature in JavaScript and that is the ability to merge code from all different sources into one web page. Your code, Google's code, Joe Smith's code can all be put into one web page and work all together. We have already seen this with our reference to jQuery. You didn't write that code, did you? but its there in your page and it works. So what is the problem with this? Let's load up some simple code
<!DOCTYPE html>
<!--
<!--
<!--
<!-- <html class="no-js"> <!--
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
</head>
<body>
<!--
<!--
<p>Hello world! This is HTML5 Boilerplate.</p>
<script >
var $ = "what up dollar sign";
alert($);
</script>
</body>
</html><span style="font-size: 9pt;"> </span>
Note: I removed the reference to jQuery. So if you load this page you'll see and alert dialog with the text "what up dollar sign". Ok now lets add the reference to jQuery back but put it in the middle of our code
<script >
var $ = "what up dollar sign";
</script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script >
alert($)
</script>
If you load the page now, you'll no longer see "what up dollar sign" in the dialog box. Where it go? jQuery itself uses the dollar sign as a variable and so when it gets loaded it overwrites what you put in your dollar sign variable.
Lesson 5
Its best practice to have only one variable attached to the global object and have the rest of your code run off of that. For example, in jQuery they use the "$" as the one variable that is attached to the global object. This is what is sometimes called a namespace. You choose one special unique variable name that nobody else would probably use and that will be where all your code is attached to. So let's try to use that to implement our complex dollar sign code in our namespace so that jQuery doesn't overwrite it
<!DOCTYPE html>
<!--
<!--
<!--
<!-- <html class="no-js"> <!--
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
</head>
<body>
<!--
<!--
<p>Hello world! This is HTML5 Boilerplate.</p>
<script >
var myspecialvariablename = {$:"what up dollar sign"};
</script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script >
alert(myspecialvariablename.$)
</script>
</body>
</html>
So if you load this code in your page in run it, you will again see the alert box with "what up dollar sign", jQuery didn't overwrite it. So if we put everything together we might have something like this:
<!DOCTYPE html>
<!--
<!--
<!--
<!-- <html class="no-js"> <!--
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
</head>
<body>
<!--
<!--
<p>Hello world! This is HTML5 Boilerplate.</p>
<div id="div1">I want to be blue.</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script>
var mynamespace = {
initializePage:function(){
var div1 = document.getElementById("div1");
div1.style.backgroundColor= 'blue'
}
};
</script>
<script >
$(mynamespace.initializePage)
</script>
</body>
</html>
OK, that's it for now. I'll continue on in another article hopefully.