Blog Post RSS ?

Blogs » JavaScript & CSS » Closures and executing JavaScript on page load
 

Closures and executing JavaScript on page load

by Simon Willison

Over on my other blog I’ve just published a new technique for executing a piece of JavaScript once a page has finished loading. Here’s the code:


function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      oldonload();
      func();
    }
  }
}

addLoadEvent(nameOfSomeFunctionToRunOnPageLoad);
addLoadEvent(function() {
  /* more code to run on page load */ 
});

My other post has a run-down of why this technique is needed and an explanation of how it works, but I’d like to expand on that here by talking about the way the above code uses a JavaScript language feature known as a closure.

A closure consists of a function along with the lexical environment (the set of available variables) in which it was defined. This is a remarkably powerful concept, and one commonly seen in functional programming languages such as JavaScript. Here’s a simple example of closures in action:


function createAdder(x) {
  return function(y) {
    return y + x;
  }
}

addThree = createAdder(3);
addFour = createAdder(4);

document.write('10 + 3 is ' + addThree(10) + '
'); document.write('10 + 4 is ' + addFour(10));

createAdder(x) is a function that returns a function. In JavaScript, functions are first-class objects: they can be passed to other functions as arguments and returned from functions as well. In this case, the function returned is itself a function that takes an argument and adds something to it.

Here’s the magic: the function returned by createAdder() is a closure. It “remembers” the environment in which it was created. If you pass createAdder the integer 3, you get back a function that will add 3 to its argument. If you pass 4, you get back a function that adds 4. The addThree and addFour functions in the above example are created in this way.

Let’s take another look at the addLoadEvent function. It takes as its argument a callback function which you wish to be executed once the page has loaded. There follow two cases: in the first case, window.onload does not already have a function assigned to it, so the function simply assigns the callback to window.onload. The second case is where the closure comes in: window.onload has already had something assigned to it. This previously assigned function is first saved in a variable called oldonload. Then a brand new function is created which first executes oldonload, then executes the new callback function. This new function is assigned to window.onload. Thanks to the magical property of closures, it will “remember” what the initial onload function was. Further more, you can call the addLoadEvent function multiple times with different arguments and it will build up a chain of functions, making sure that everything will be executed when the page loads no matter how many callbacks you have added.

Closures are a very powerful language feature but can take some getting used to. This article on Wikipedia provides more in-depth coverage.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Ping.fm
  • Twitthis

Related posts:

  1. Google Releases its JavaScript Closure Tools Do we need more JavaScript libraries and tools? Perhaps not,...
  2. Implementing Event Latency in JavaScript Craig provides some useful JavaScript code to slow down event...
  3. How to Write a Cookie-less Session Library for JavaScript Craig provides the code for a stand-alone JavaScript session variable...
  4. Fixing Object Instances in JavaScript Even experienced coders can get caught out by object handling...
  5. An Introduction to JavaScript for Acrobat I’m always interested to see how JavaScript works on non-browser...

This post has 48 responses so far

Sponsored Links

SitePoint Marketplace

Buy and sell Websites, templates, domain names, hosting, graphics and more.

Follow SitePoint on...