This article addresses the difficulty and a possible solution to completely separate JavaScript from HTML e.g. event assigning attribute like onclick and more importantly onload.
Suppose your HTML page -
myPage.html, looks something like this
myPage.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head><title>Separating JavaScript from HTML</title>
</head>
<body>
<p>Type your name here: <input id="userName" type="text" />
<button id="btnProceed">Proceed</button></p>
</body>
</html>
Now, here is the specific task description:
- Assign an onclick event handler for the 'Proceed' button
- This handler method should read the 'userName' input field and display a greeting message to welcome the user. If blank, inform user accordingly.
- Do not use HTML attributes to assign events e.g. onclick, onload etc. The whole idea is to follow a more methodical approach while dealing with events and thereby obtain a clean HTML; just what we have been doing for 'look and feel' aka CSS.
Ok, we will first include the external JS file:
myPage.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head><title>Separating JavaScript from HTML</title>
<script language="JavaScript" type="text/javascript" src="myPage.js"></script>
</head>
<body>
<p>Type your name here: <input id="userName" type="text" />
<button id="btnProceed">Proceed</button></p>
</body>
</html>
Now, the real action. Let's start writing the JavaScript code; but here are some tips:
- Have a single JavaScript Object, say oMyPage, to represent one HTML page. This should help you avoide any global variable declarations; you can have them as properties of this object.
- Remember, ALL functionality you need for your HTML page should be comprised either as method or as property of the oMyPage object.
- Define an initializer method which will take care of all event assigning task for necessary HTML elements. (Later on we'll set this method to be invoked automatically when our HTML page is completely loaded and ready.)
- Always describe your method and property declarations with the help of comments. This will make the code maintenance easier.
- Do not overlook the importance of proper indentation and self-explanatory but brief names (necessarily in the same order of priority) for your object members. Believe me, it doesn't take more than 1% of the total coding efforts.
myPage.js
//object to represent myPage.html
var oMyPage = {
//default initialize method
init: function(){
//get the button element
this.btnProceed = document.getElementById("btnProceed");
if (this.btnProceed) { //avoid exception
if (this.btnProceed.addEventListener) { //non-IE
this.btnProceed.addEventListener("click",this.greetUser,false);
}else if (this.btnProceed.attachEvent){ //IE
this.btnProceed.attachEvent("onclick",this.greetUser);
}
}
},
//method to read username inputbox and display greeting message
greetUser: function(){
//collect userName inputbox
var ibUserName = document.getElementById("userName");
var sUserName = '';
if (ibUserName) { //avoid exception
sUserName = ibUserName.value; //read
if (sUserName == '') { //check for blank entry
alert("Please enter your name");
} else { //greet user
alert("Welcome '" + sUserName + "'");
}
}
}
}
//set oMyPage object's initialize method to get invoked automatically when HTML page is ready
window.onload = function() {
window.setTimeout(function() { //especially for IE, setTimeout will make sure the page is ready. Later on we will have another post which will provide a better solution to check the document ready state.
oMyPage.init();
}, 10);
}
Of course, with the help of a wrapper like prototype.js, we can get rid of browser conscious code. But the point here was to handle this task with core JavaScript.
Please have a look at the member names. Prefixes can be used to describe types e.g. o for object, s for string etc. Definitely, one can think of his/her own naming convention rules. Also, defining these conventions somewhere in the file, preferably at the bottom, would be a great idea.
Concluding, this might not be a perfect solution. So, kindly leave your comments to improve this snippet further.
Cheers!
Kumar
UI Architect