Writing Good Javascript
Suggestions with small description
1.
Javascript
Code Must Be browser compatible. We must check in FireFox and IE if javascript is
working perfectly during development of a complex function. Not after completing
all functions. It will save many hours which may need to re-code by checking all
functions after error found.
Bad Example:
function
IsNumeric() // this will not work in FireFox
{
KeyID =
window.event.keyCode;
if(
(KeyID >= 46 && KeyID <
58) ||KeyID < 32)
{
return
true;
}
else
{
return
false;
}
}
Good Example:
function
IsNumeric(e)
{
try
{
var KeyID;
var res = navigator.appName;
if(res == "Microsoft Internet Explorer")
{
KeyID
= window.event.keyCode;
}
else
{
strTemp
= String.fromCharCode(e.which);
KeyID
= strTemp.charCodeAt(0);
}
try
{
if( (KeyID >= 46
&& KeyID < 58) ||KeyID < 32)
{
return true;
}
else
{
return false;
}
}
catch(ex)
{}
}
catch(ed){}
return
true;
}
2.
Javascript
variable names must have predefined prefix for different data types. We should use
same prefix using in C# code. Plus some extra prefix for most common objects in
javascript. For example, div for Div, tbl for Table, tr for TR, td for TD etc.
3.
We should
not write javascript code in .aspx file. We can use separate single/multiple javascript
file for each module.
4.
We must
use try – catch in all functions / complex code blocks. By this way javascript will
not stop executing if an error occurred in one section.
5.
Javascript
Code Must Be well aligned. (Visual Studio 2005 does not align javascript code automatically.
Even we can not align by pressing ctrl+k+d). We must keep alignment manually.
Bad Example:
function
SetDivHeight()
{
var
valu;
try{
var obj1
= document.getElementById("Defaultbody");
var objDiv
= document.getElementById("divGrid");
valu = obj1.offsetHeight;
// objDiv.style.height = "250";
objDiv.style.height = valu - 50;
//alert(valu);
return;
}
catch(Ex)
{}
return;
}
Good Example:
function
SetDivHeight()
{
var
iHeight;
try
{
var divBody = document.getElementById("Defaultbody");
var
divGrid = document.getElementById("divGrid");
iHeight
= divBody.offsetHeight;
divGrid.style.height = iHeight - 50;
return;
}
catch(Ex)
{
}
return;
}
6.
Try to
keep javascript file lighter by removing unnecessary commented code blocks + by
using small variable / function names. We
can use prototype.js javascript framework which has shortcut names for all-too-frequent
long functions ($(), $$() , $F(), $A(), $H(), $R() etc). For example:
$(“divGrid”) is for
document.getElementById(“divGrid”)
Bad Example:
function
GetSalesOrderPageUrl()
// for Product Page(Details/Information)
{
//var url = "../CRM/AccountContactUI.aspx?NavigateId=" + DisplayPageUrl;
var
ifrmPage = GetElementByTagId("CurrentPageID","IFRAME");
//var
oSrc = queryStringC("NavigateIdF");
var
oSrc = "../Site.aspx?NavigateId=" + document.getElementById("hfOrderId").value;
// var objUrl = document.getElementById("hfUrl");
//
if(objUrl.value == "0")
// {
//
objUrl.value = oSrc;
//
}
// return oSrc;
ifrmPage.src = oSrc;
var
ChkInProgress = document.getElementById("ctl00_cphPage_rdInProgress");
var ChkShipped = document.getElementById("ctl00_cphPage_rdShipped");
var ChkPartiallyShipped = document.getElementById("ctl00_cphPage_rdPartially");
var ChkReceived = document.getElementById("ctl00_cphPage_rdReceived");
var ChkAuthorised = document.getElementById("ctl00_cphPage_rdAuthorised");
var ChkPayCancel = document.getElementById("ctl00_cphPage_rdPSCancelled");
if(ChkInProgress.checked ||ChkShipped.checked ||ChkPartiallyShipped.checked)
if(ChkReceived.checked ==
false && ChkAuthorised.checked == false
&& ChkPayCancel.checked == false)
{
alert("Error Message");
}
else
__doPostBack('ctl00$mnuPageToolbar','Save');
else
__doPostBack('ctl00$mnuPageToolbar','Save');
}
Good Example:
function
GetSalesOrderPageUrl()
// for Product Page(Details/Information)
{
var
ifrmPage = GetElementByTagId("CurrentPageID","IFRAME");
var
oSrc =
"../Site.aspx?NavigateId=" + $("hfOrderId").value;
ifrmPage.src
= oSrc;
var
chkInProgress = $("ctl00_cphPage_rdInProgress");
var
chkShipped =
$("ctl00_cphPage_rdShipped");
var
chkPartiallyShipped = $("ctl00_cphPage_rdPartially");
var
chkReceived = $("ctl00_cphPage_rdReceived");
var
chkAuthorised = $("ctl00_cphPage_rdAuthorised");
var
chkPayCancel = $("ctl00_cphPage_rdPSCancelled");
if(chkInProgress.checked
||chkShipped.checked )
{
if(chkReceived.checked == false
&& chkAuthorised.checked == false)
{
alert("Error Message");
}
else
{
__doPostBack('ctl00$mnuPageToolbar','Save');
}
}
else
{
__doPostBack('ctl00$mnuPageToolbar','Save');
}
}
7.
We should
not use inline hard coded error success messages which are showed to user. Instead
we should define messages at a common place, and then use only reference in codes.
By this way it will be very easy to change message text / check grammar or spellings
very easily. We can define very common messages in a common file. And other messages
at the top of each javascript file.
Bad Example:
function
ValidateFields()
{
RE_EMAIL_ADDRESS =
/^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,3}|[0-9]{1,3})(\]?)$/;
email = document.getElementById('ctl00_cp_txtEmail').value;
if( email == "" )
{
alert(
"Please enter email");
return
false;
}
if( !RE_EMAIL_ADDRESS.exec(email) )
{
alert(
"Please, enter email address in valid format. i.e. yourname@yourservername.com.");
document.getElementById('ctl00_cp_txtEmail').focus();
return false;
}
return true;
}
Good Example:
try
{
/*================== Start Of Defining Messages =====================*/
var
MSG_EMAIL_REQUIRED = "Please, enter email address in valid
format.";
var
MSG_INVALID_EMAIL =
"Email address is required.";
/*================== End Of Defining Messages =====================*/
/*=============== Start Of Defining Regular Expressions ===========*/
var
RE_ZIPCODE = "/\d{5}(-\d{4})?/";
var
RE_EMAIL =
"/^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,3}|[0-9]{1,3})(\]?)$/";
/*=============== End Of Defining Regular Expressions ===========*/
}
catch(ex)
{
}
function
ValidateFields()
{
var
txtEmail = $('ctl00_cp_txtEmail').value;
if(txtEmail
== "" )
{
alert(MSG_EMAIL_REQUIRED);
return
false;
}
if(
!RE_EMAIL.exec(txtEmail) )
{
alert(MSG_INVALID_EMAIL);
$('ctl00_cp_txtEmail').focus();
return
false;
}
return
true;
}
8.
Always
use ‘var’. it is good practice to use var as there are two cases in functions
where it is necessary:
If a global variable of the same name exists.
If recursive or multiple functions use variables of the same name.
Bad Example:
MSG_EMAIL_REQUIRED
= "Please, enter email address in valid format.";
MSG_INVALID_EMAIL = "Email address
is required.";
Good Example:
var
MSG_EMAIL_REQUIRED = "Please, enter email address in valid
format.";
var
MSG_INVALID_EMAIL =
"Email address is required.";
9.
Detect special attributes if exists before use.
To make our code browser compatible it is important to check if the attribute is
valid or not in current browser. For
example the attribute window.event.keyCode
is not supported by FireFox. So we should write
Bad Example:
var
KeyID = window.event.keyCode;
Good Example:
if(window.event.keyCode)
{
KeyID =
window.event.keyCode;
}
10.
Use second
bracket indexing instead of dot notation to access attributes. It will help us to
access attributes within loop. For example, we can access myObj[“value”+i] but can
not access myObj.value+i
Bad Example:
var
txtName = document.formName.name.value;
Good Example:
var
txtName = document.forms["formName "].elements["name"].value;
11.
Avoid using eval(). "Eval is evil." Don't use it unless you are an experienced developer
and know that your case is an exception. Normally you can access useing second bracket
notification instead of eval().
Bad Example:
var
txtName = eval(“document.formName.name”+i+”.value”);
Good Example:
var
txtName = document.forms["formName"].elements["name"+i].value;
12.
Avoid
using document.formName.
Though some browsers make the form available as a property of the document itself using its name. This is not reliable
and shouldn't be used.
Bad Example:
var
txtName = document.formName.name;
Good Example:
var
txtName = document.forms["formName "].elements["name"];
13.
Avoid using
the “with”
statement. This is often used as a shortcut to avoid multiple long references.
But the problem is that the programmer
has no way to verify that input1 or input2 are actually being resolved as properties
of the form elements array. It is checked first for properties with these names,
but if they aren't found then it continues to search up the scope chain. Eventually,
it reaches the global object where it tries to treat "input1" and "input2" as global
variables and tries to set their "value" properties, which result in an error.
Instead, create a reference to the
reused object and use it to resolve references.
Bad Example:
with (document.forms["mainForm"].elements) {
input1.value = "junk";
input2.value = "junk";
}
Good Example:
var
elements = document.forms["mainForm"].elements;
elements.input1.value
= "junk";
elements.input2.value
= "junk";
14.
Use onclick In Anchors Instead Of javascript: Pseudo-Protocol.
Also remember that the word is onclick. Not onClick .
Bad Example:
<a href="javascript:doSomething()">link</a>
<a href="#"
onClick="doSomething()">link</a>
<a href="#"
onClick="javascript:doSomething();">link</a>
<a href="#"
onClick="javascript:doSomething(); return false;">link</a>
Good Example:
<a href="somepage.aspx"
onclick="javascript:doSomething(); return false;">link</a>
15.
Avoid using
“document.all”.
It was introduced by Microsoft in IE and is not a standard javascript DOM feature.
Although many newer browsers do support it to try to support poorly-written scripts
that depend on it, many browsers do not.
Bad Example:
var
frmMyForm = document.all("mainForm”);
Good Example:
var
frmMyForm = document. getElementById("mainForm”);
16.
Don't Use HTML
Comments In Script Blocks. No browsers in common use today are ignorant of the <script>
tag, so hiding of javascript source is no longer necessary. In fact, it can be considered
harmful for the following reasons:
i) Within XHTML documents, the source
will actually be hidden from all browsers and rendered useless
ii) -- is not allowed within HTML
comments, so any decrement operations in script are invalid
Bad Example:
<script language="javascript">
<!--
// code here
//-->
</script>
Good Example:
<script language="javascript">
// code here
</script>