One of the main things that really blows programmers’ minds when they really see the power of it is a topic called ‘closures’ or ‘lambda functions’ or ‘anonymous subroutines’.
I decided to edit the previous post’s code to use closures, to get the hang of this technique in JavaScript. It makes your code a lot more flexible as I think the simple example below demonstrates.
For the code, look after the jump…
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>untitled</title>
<meta name="generator" content="TextMate http://macromates.com/">
<meta name="author" content="Steven Harms">
<!-- Date: 2006-08-19 -->
<script type="text/javascript" charset="utf-8">
function addParagraph (manipulateText){
var childEl = document.createElement('p');
// This is something subtle, you need to create a text node and bond
// that to the <p> element. In the DOM inspector, this shows
// up as 'nodeName' = #text
var tf = document.createTextNode("Moopy hobo");
// Bond the text to the <p> element
childEl.appendChild(tf);
// If we didn't get a closure, i think they're going to
// do something with it in the calling section, they can have
// the node back
if (typeof manipulateText == 'undefined'){
return childEl;
}
// But...if they sent me how to manipulate ahead of time, then
// I'll do that
return manipulateText(childEl);
}
function configurePage(doTextChange){
//Get the HTML <body> tag reference
var htmlParent = document.getElementsByTagName('Body')[0];
// Create a blank <p> tag reference
var childEl = document.createElement('p');
//Load this up as a usable <p> element, but then do some
// style based operations on it. Operations are passed as
// a closure ( i.e. a pointer to code) as the first argument
childEl = addParagraph(
function (node) {
node.style.width="200px";
node.style.fontFamily="garamond; helvetica";
node.className='graybackground';
node.addEventListener('mouseover',changebk,false);
node.addEventListener('mouseout',dazzle,false);
return node;
}
);
// Handle the argument
if ( doTextChange == 'YES' ){
childEl.firstChild.nodeValue="Monsieur Hobo"
}
//Finally, put this loaded up <p> tag onto the page by appending
//it to the <html><body> node
htmlParent.appendChild(childEl);
}
// A function for callbacks, the alert() is pretty annoying when
// testing so I've commented it out, but enabling it makes things
// a bit more obvious
function dazzle(){
alert('you are dazzled');
this.className='graybackground'
}
//Nifty!
function changebk(){
this.className='redbackground'
}
</script>
<style type="text/css" media="screen">
.graybackground{
background-color: #BBB;
}
.redbackground{
background-color: red;
}
</style>
</head>
<body onload="configurePage('YES')">
<!-- Look Ma, no content! -->
</body>
</html>