NovoGeek.com - Krishna's weblog

A technical blog on jQuery, AJAX, JavaScript & modern web technologies

"Global variables are evil" is what the JavaScript Guru Douglas Crockford says, as they are the source of unreliability and insecurity. How elegant your code would be if you wrap your entire project's code under a single global namespace?

[Did you know? The entire JavaScript code of Yahoo's website is accessible through a single global 'YAHOO' object!]

In this article, I would like to show how you can create a chainable JavaScript library(not a library exactly, but sort of a toolbox) specific to your project. The concept is nothing new., this is how libraries like jQuery are built. It is more about understanding certain design patterns in JavaScript.

The first thing to know is:

(function(){ 
    //your code here....
})(); 

This is nothing but a self executing anonymous function. All it does is, it simply executes whatever code you write inside it and disappears after that. The private variables declared inside this function are not exposed to the global scope, unless specifically attached to the window object.

The next thing to know is about Prototypal Inheritance in JavaScript. This is a huge topic in itself and the article assumes that the reader is familiar with this concept. The idea is, in our anonymous function, we would have a private function and prototype it with our custom functions.

This is how our JavaScript toolbox looks like: 

(function(){
    var mySpace=function(){
        return new PrivateSpace();
    }
 
    var PrivateSpace=function(){
    };    
 
    PrivateSpace.prototype={
        init:function(){
            console.log('init this:', this);
            return this;
        },
        ajax:function(){
            console.log('make ajax calls here');
            return this;
        },
        cache:function(){
            console.log('cache selectors here');
            return this;
        }
    }
    window.my$=mySpace();
})();

In the above code, "PrivateSpace" is a private function which is prototyped with our desired functions. "mySpace" is a function which returns a new instance of "PrivateSpace" when executed.

As said before, our anonymous function executes once and does not expose these functions to the outer world. To expose our functions under a namespace, we should add the instance of our "PrivateSpace" to a window level(global) object. This is exactly what the last line of the code does.

So, when we say

window.my$=mySpace(); 

we are executing "mySpace()", which returns a new instance of  "PrivateSpace()" function and assigning it to "my$", which is a window level object. So if you print my$ like:

console.log(my$);

, you would get all the functions present in the "PrivateSpace()" prototype. So you can call your functions like: my$.ajax(), my$.cache() etc.

Note that each function in "PrivateSpace()" returns "this". i.e., each function returns an instance of "PrivateSpace()" and hence you can chain your methods like:

my$.init().ajax();

That's it! Now we have our own JavaScript toolbox specific to our project! So no more global functions in our projects. As said, this is nothing new to the JavaScript world,  this pattern is what jQuery uses for chaining the methods.

I have faced few problems while opting for this pattern and posted them in StackOverflow. Folks there are kind to answer and hence this article. I'm no JS guru to say this is 100% perfect, but I have implemented this without any issues in a huge project.  You may refer Chapter 6 (Chaining) in  Pro JavaScript Design Patterns which explains about this jQuery like pattern.

Do you have better ideas? Please let me know.

Happy coding :)


Before starting with the article, I would like to share something which encouraged me a lot. Now I'm a Microsoft Most Valuable Professional (MVP) for ASP.NET. Thanks to Microsoft folks for recognizing my efforts. :)

 

Coming to the point., have you ever faced the below “Stop running script” error message in your thick client web apps? This is one of the most frustrating errors, which hangs the browser, spikes CPU usage and slows down your operations.

 

 

Nicholas C. Zakas has an excellent article on why it occurs in various browsers. In short, his research says that the error occurs in various browsers due to exceedingly high number of operations taking place(~5 million statements in IE), or due to script executing for a very long time(~10 secs in FF).

For best performance, Nich says that no script should take longer than 100 ms to execute on any browser, at any point of time.

 

Now, why should jQuery developers worry about this?

They should, because jQuery is made of nothing but JavaScript and chances of getting this error are more, if you don't understand the core methods properly. Let's see in detail what this means.

 

Take the below script as example. Execute in Firebug console or in IE8 script panel or simply copy/paste in a html file and open it.

(function exec(){ 
    var str=''; 
    for(i=0;i<10000;i++) 
    { 
        str+='<div>test div '+i+'</div>'; 
    } 
    $('body').append('<div id="TestDiv"></div>');
    $('#TestDiv').html(str); 
})();

Note: The above code might crash your browser. So please try in stand alone instance. If you are not getting the error or experiencing different behaviour, probably you have better CPU which does not spike up to 100% for this code. The point here is about wrong usage of code. So increasing the max condition should give the error. This analysis is as per jQuery version: 1.3.2.

 

What I'm doing here is pretty straight forward. Just looping and creating 10000 elements and injecting them into the DOM. Now, what's so important here?

It's just a simple piece of code. 10000 operations in a loop is way beyond the threshold of 5 million operations. When you run this code for the first time, browser stops responding and when you run this for the second time, you get the 'stop running script' error.

 

This might sound silly at a first glance. Such huge loops will obviously cause such errors. But what if you are doing this in your code without your knowledge? Do you know that this error occurs in several facebook apps & in twitter? There is something beyond the loop.

 

$().html vs element.innerHTML:

Replace the line:

$('#TestDiv').html(str);

with this one:

$('#TestDiv')[0].innerHTML=str;

and now try. We are using native JavaScript's innerHTML to inject DOM elements. This is faster than jQuery's .html() and hence no error.

 

Does this mean this is the mistake of jQuery?? No! It's purely developer’s ignorance. First of all, such huge DOM manipulations should not be made (This is commonly used, unknowingly.). Then, you should be aware of what .html() does.

 

$(‘selector’).html() internally removes event handlers attached to every child element in the selector’s DOM tree , cleans up the incoming mark up by adding unclosed tags and then injects the new mark up. So for the first time, since no DOM elements were there, .html() only cleans the new mark up and injects it. For the second time, it has the additional task of removing the event handlers and hence the number of operations are increased, giving the error.

 

So when should I use .innerHTML and when should I use .html()?

Genuine doubt! Use .innerHTML if you are SURE that you have to JUST replace the mark up, provided your mark up does not contain any events attached to it. Use jQuery’s .html() when you want to unbind events attached to elements and take care of garbage collection/memory leaks. (You may refer to “jQuery cookbook” for more info on this).

 

This is not the only pitfall. JavaScript’s native for(;;) loop is faster than jQuery's $.each() loop. So before enjoying the benefits of the library, analyze the bottle necks too.

 

(Q) When does such scenarios arise? Why would someone loop some 10000 times in their code?

(A) Though practically no developer loops ten thousand times in his code, knowing that it’s a performance issue, people tend to make this mistake unknowingly. The analogy here is about larger DOM manipulations. I shall explain such scenarios in my next article.

 

Happy coding :)


The term "presentation" has almost become synonymous with Microsoft Office PowerPoint. Yup, without doubt it is the sole leader among s/w for presenting stuff and is improving in every version, the only problem being - difficulty in sharing the presentation.

With the emergence of Web 2.0 sites like SlideShare.net, sharing ppt's on the web has become quite easy. There are several web based alternatives which are gaining popularity these days. They have the benefit of creating/editing/sharing the presentations entirely on the browser.

However, for web devs, having more flexibility on code would give better control, as they can show code/inline demos in the presentation itself! John Resig's tutorial on Advanced JavaScript is an excellent example for the powerful inline demos.

There are XHTML based tools which have pre-built slide show features, the famous ones being: S5 (A Simple Standards based Slide Show System) and HTML Slidy. They provide many features like navigating using keyboard shortcuts, mouse clicks etc., simulating a powerpoint presentation.

With the advent of jQuery, things have become even more easier! The recent release of jQuery 1.4 had a slideshow based on jQuery code, which was awesome. 

I had my own presentation template prepared using coda slider effect and it got good feedback :)

Now there is jQuery presentation plugin specifically for creating presentations! It came floating in my flood of tweets, thanks to Twitter & Trevor Davis (author of the plugin)!

By the way, if you want to prepare a simple slide show which slides automatically across .html files, don't struggle with complex JavaScript code. Just use the META refresh tag. Change the "URL" attribute of the tag so that it points to the next slide(html page). After the time interval set in "content" attribute is reached, automatic redirection to next slide takes place.

So lot's of interesting options for presenters/modern web devs! Let's wait for HTML5 for more hi-fi stuff like displaying 3D transitions & making the most of canvas element in the presentation itself!

Hope this article interests budding presenters like me :) Happy presenting! Smile


JavaScript closures is one of those topics which, I always thought, is beyond my head. Though several articles explain the concept, somehow, I was often confused.

I was working on a thick client application, which heavily uses lot of jQuery and JavaScript. I need a client side timer to run periodically, to keep user's session alive and so I was using JavaScript's native "setInterval()" method for my timer. Everything was fine, till I suddenly faced a weird problem.

Suppose, you have created a  global function which is to be fired periodically. In simple JS, it can be written as:

var timer=function (){ 
    console.log('my timer'); 
}; 
var timerId=setInterval('timer();',1000); 

This works perfectly well. Here the function "timer()" is at a window level and has global scope. So no issues so far.

However, to clean up the code, if you follow any of these patterns,  you will have good code, but setInterval will not work! See the below code for more clarity:

var TestObject=function(){ 
    var timerId; 
    this.timer=function(){ 
        console.log('test timer'); 
    }; 
    this.startTimer=function(){ 
        timerId=setInterval(function(){ 
            this.timer(); 
        },1000); 
    }; 
    this.stopTimer=function(){ 
        clearInterval(timerId); 
    }; 
}; 
 
var obj=new TestObject(); 
obj.startTimer(); 
obj.stopTimer(); 

In the above code, TestObject is the class which is holding the entire code, so that all my functions are not exposed to global window object. "timer()" is a public function which will be fired periodically and "startTimer()" is the function which will trigger the timer.

If you run the above code (you can quickly try in firebug console), you will get a JavaScript error - "this.timer is not a function". The reason is, setInterval() function will take the scope to window object and this will check for "timer()" at window level. Since you are wrapping it in "TestObject", "timer()" will not be found. To solve this scope problem, you need to use closures and store the instance of the class. So the "startTimer()" function should be like:

this.startTimer=function(){ 
      var inst=this; 
      console.log('startTimer this: ',this); 
      timerId=setInterval(function(){ 
          console.log('setInterval this: ',this); 
          inst.timer(); 
      },1000); 
}; 

The above code has two console statements. The “this” keyword in the first console statement prints the instance of TestObject, while the “this” keyword in setInterval function prints “window” object. This shows that setInterval function will take the scope to window level and hence it is not able to find “this.timer” in the first snippet.

Notice that we are storing the instance of TestObject class in a local variable "inst". Also notice that setInterval is using an anonymous function, which is forming a closure. In this anonymous funtion, we are able to access timer() function using "inst.timer()". This would solve the scope problem! setInterval function will be called for every 1 second and it will always have access to “inst.timer()”. This is the power of closures.

To explain closures in my words,  when there are nested functions, the child function will have access to local variables of parent function(which is as expected). But after the parent function has executed, the child function, when called explicitly, will still have access to the local variable of parent function. JavaScript garbage collector will not clear the value of the variable.

For a graphical explanation of JavaScript closures in jQuery context, please check BenNadel's blog. Ben explains the concept of closures very clearly in this article.

Happy coding :)


The goal of this article is to educate budding jQuery developers (who do not have much exposure to JavaScript), to write clean, readable, maintainable code. This is in fact, a pointer to articles written by several JavaScript gurus.

For a jQuery developer, who does not have good expertise of JavaScript object oriented programming concepts, the entire code of a JavaScript file would reside in the "$(document).ready()” function. This includes various events, ajax calls, their call backs, UI effects etc.

In the case of a large scale business application (having hundreds of JavaScript files, each file having few thousands of lines), this would mean a lot of effort during reviews, white box testing and especially maintenance. Therefore, apart from learning the library, knowledge of good practices of core JavaScript language is a must.

Here is a collection of some of the best links, which would change the way you code. Read them in this sequence :)

1. JavaScript Best Practices by Christian Heilmannhttp://dev.opera.com/articles/view/javascript-best-practices/

2. Show love to the object literal - http://www.wait-till-i.com/2006/02/16/show-love-to-the-object-literal/

3. Closures and lexical scoping in JavaScript - http://mark-story.com/posts/view/picking-up-javascript-closures-and-lexical-scoping

4. Private Members in JavaScript by Douglas Crockford - http://www.crockford.com/javascript/private.html

5. JavaScript programming patterns - http://www.klauskomenda.com/code/javascript-programming-patterns 

6. Five things to do to a script before handing it over to the next developer - http://www.wait-till-i.com/2008/02/07/five-things-to-do-to-a-script-before-handing-it-over-to-the-next-developer/

Out of all the JavaScript design patterns in link #5, these are quite popular:

 a. Singleton pattern [Thanks to HB Stone for explaining the concept in simpler terms]

 b. Module pattern [Thanks to Christian Heilmann for the contribution]

 c. Revealing module pattern [An updation to module pattern by Christian Heilmann]

I have tried these and like many others, I fell in love with the Revealing module pattern. The core of these patterns is the concept of closures. So make sure you are good at the basics!

Before trying out patterns, my jQuery code was like this:

$(document).ready(function() {
   //page load ajax call 
    $.ajax({
        type: "POST",
        url: "CTypesHandler.ashx",
        data:"{}",
        success: callBackFunction,
        error: function(){}
    });
 
    //ajax success callback function
    callBackFunction(response)
    {
        //process ajax response here...
    }
    
    //form validation code
    $('#FormId').validate(){
        //code for validation
    }
    
    //click events
    $('#submitButton').click(function(){
      //code for submit click event
    });
    
    $('#saveButton').click(function(){
      //code for save click event
    });
});

After trying out Revealing Module pattern, my jQuery code is very clean like this:

var mySamplePage=function(){
    var counter=0;
    
    var callBackFunction = function(response)
    {
        //process ajax response here...
    };
    
    var pageLoadAjaxCalls=function(){
        $.ajax({
            type: "POST",
            url: "CTypesHandler.ashx",
            data:"{}",
            success: callBackFunction,
            error: function(){}
        });
    };
    
    var bindEvents=function(){
        $('#submitButton').click(function(){
          //code for submit click event
            counter++;
        });
        
        $('#saveButton').click(function(){
          //code for save click event
        });
    };
    
    var validate=function(){
      $('#FormId').validate(){
          //code for validation
      };
    };
    
    var pageLoadOperations=function(){
        validate();
        pageLoadAjaxCalls();
        bindEvents();
    };
    
    return{
        init:pageLoadOperations
    };   
}
 
$(document).ready(function(){
    vare page= new mySamplePage();
    page.init();
});

To explain the differences in short, the first snippet has all code in document.ready function. This means, all variables, functions used are global. There is no modularization in the code. So if new events, UI logic are to be added, they add up to the mess.

In the case of patterns snippet, the code is clearly modularized. There are no global variables/functions. All members, functions are private. Only certain methods are exposed(by adding pointer in return statement). If new code has to be added in future, it can be added to the respective functions (like pageLoadAjaxCalls, bindEvents etc). Our document.ready is now very clean, and has control on what to be done, with ease.

Using good jQuery selectors gives optimized code; Using JavaScript design patterns gives clean and maintainable code. Happy coding :)


A beautiful presentation given by John Resig, creator of jQuery, at Google. John covers the latest improvements in the modern browsers namely Firefox 3.1, Safari 4.0, Internet Explorer 8.0, Google Chrome and Opera 10. You can find the video presentation here @ Youtube and the pdf format of the presentation here @ Slideshare. A must see presentation for the modern web developer :)

In ASP.NET, we are used to drag/drop server controls and quickly finish the task, though we do not concentrate much on how they work. The problem arises when JavaScript is disabled in the user's browser, as some of these controls do not work.

Also, if you have rich AJAX features in your site, they will fail miserably if JavaScript is disabled in the browser. Ideally, your client expects the site to work even when JS is disabled in the browser.

Here are some of the ASP.NET server controls which which depend on client script for their functionality:

  • The LinkButton and HtmlButton server controls require JavaScript. (However, the Button Web server control, the HtmlInputButton or HtmlInputImage controls work fine.)

  • Any Web server control whose AutoPostBack property is set to true need client script so that the control will post the page to the server.

  • The Validation controls require client script to support client-side validation. If the client does not support script, validation will run on the server only.

  • Gridview pagination, sorting will not work. Custom pagination has to be used
How to detect if JavaScript is enabled in the browser or not? Check this excellent article at Boutell.com.

So, for the site to still work without JavaScript, use <noscript></noscript> tag, place server side buttons inside the tags and write your server side code in the button click events. These tags will be visible only when JavaScript is disabled. So you will not face any issues when JS is enabled.

An irritating scenario: You need a link button to do a server side task, but it doesn't wont work without javascript.

Work around: Apply styles to server side button and make it look like link button :p
Here is the CSS code you have to write (works fine in all major browsers):

.NewLinkButton
{
background-color:Transparent;
border-style: none;
color:Navy;
cursor: pointer;
display:inline-block;
font-style:normal;
text-align: left;
text-decoration:underline;
}

Please check the MSDN article: ASP.NET Web Server Controls that Use Client Script for more valuable info.


Most of the AJAX introduction sessions give a demonstration of drag/drop features. I've attended an AJAX session 1 year back and wondered.."Will I ever be able to do such an amazing drag/drop cart?" Hehe..thanks to jQuery UI. Drag/drop  isn't a magic anymore!

Here is a demo of jQuery drag/drop shopping cart. Simply drag the items into the basket and total will be calculated. You may also remove the items from the basket, everything without postback.


All that started with a simple tweet by a Norwegian developer Erlend Schei. He came up with an idea to display an "Upgrade" message on IE6 browsers for his websites and suddenly, all major websites of Norway adopted it, thereby declaring a war on IE6. According to wired.com, even Microsoft is supporting the campaign.

Here is a fast spreading code, appearing on the internet, to support the campaign. This conditional code when included in our sites, appears as a message at the top when the site is opened in IE6 .
 
<html>
<head>
<title>No IE6 campaign!</title>
</head>
<body>
<!--[if lte IE 6]>
<style type="text/css">
#ie6msg{border:3px solid lightblue; margin:8px 0; background:AliceBlue; color:#000;font-family:Verdana;font-size:smaller}
#ie6msg h4{margin:8px; padding:0;}
#ie6msg p{margin:8px; padding:0;}
#ie6msg p a.getie7{font-weight:bold; color:#006;}
#ie6msg p a.ie6expl{font-weight:normal; color:#006;}
</style>
<div id="ie6msg" >
<h4>Did you know that your browser is out of date?</h4>
<p>You are using Internet Explorer 6. To get the best possible experience using our website we recommend that you upgrade your browser to a newer version. The latest version is <a class="getie7" href="http://www.microsoft.com/windows/downloads/ie/getitnow.mspx">Internet Explorer 7</a>. You may also try <a class="getie7" href="http://www.microsoft.com/windows/Internet-explorer/beta/default.aspx">Internet Explorer 8</a> which is available as a beta. The upgrade is free. If you're using a PC at work you should contact your IT-administrator.</p>
<p>You may also try other popular Internet browsers like <a class="ie6expl" href="http://www.opera.com">Opera</a>, <a class="ie6expl" href="http://firefox.com">Firefox</a> or <a class="ie6expl" href="http://www.apple.com/safari/download/">Safari</a></p>
</div>
<![endif]-->
</body>
</html>

Feel free to tweak it & use it.
In the world of browser compatibility problems, I think it's time for all of us to support this movement and reduce some pain to the developer as well as the customer...
 
Update(10th March, 2009):
The current BlogEngine theme itself looks distorted in IE6, as pointed out by one of my seniors'. So added the above code to my blog. You will get the above message when you open my blog in IE6 :)

The markup i.e., (X)HTML of your web page exists in many versions such as: HTML 4.01 Strict, XHTML 1.0 Transitional, XHTML 1.0 Strict etc. A web browser parses your web page and renders the content based on the version in which your markup exists. This information will be available to the browser though the DOCTYPE declaration. It should be declared before the <html> tag and looks like :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

Omitting DOCTYPE in the markup is one of the main reasons for cross browser compatibility issues. Sometimes, even if your mark up is valid (with XHTML and CSS), there might still be problems due to incorrect DOCTYPE.

Please go through these excellent links which explain the importance and implementation of DOCTYPE.



  • Share/Save/Bookmark
  • Entries (RSS)
  • Comments (RSS)

About

ProfilePic Hi, My name is Krishna Chaitanya and I'm a web developer from Hyderabad, India.

This is my online abode where I write about various technical topics, my little experiments related to web development in ASP.NET, jQuery etc. More...