//Bad examples
var add_the_handlers = function(nodes){
var i;
for (i = 0; i < nodes.length; i += 1) {
nodes[i].onclick = function(e){
alert(i);
}
}
};
//Better example
var add_the_handlers = function(nodes){
var i;
for (i = 0; i < nodes.length; i++) {
nodes[i].onclick = function(i){
return function(e){
alert(i);
};
}(i);
}
};
Both of these functions are suppose to assign event handler functions
to an array of nodes.
How do I test both of these?
No need to test them - Crockford explains what's going on, and it is
(relatively) easy to understand. In the first case all nodes will alert
the same value. In the latter one the proper one.
Gregor
Even better would be to use tabs and not spaces when posting (please).
> Both of these functions are suppose to assign event handler functions
> to an array of nodes.
>
> How do I test both of these?
1. Create a document with template element containing elements with the
same tag name.
<div id="template">
<span>no 1</span>
<span>no 2</span>
<span>no 3</span>
</div>
2. call add_the_handlers:
<script type="text/javascript">
var template = document.getElementById('template'),
spans = template.getElementsByTagName('span');
add_the_handlers(spans);
</script>
3. click on each span, checking to make sure that the alert displays the
expected number.
--
comp.lang.javascript FAQ <URL: http://jibbering.com/faq/ >
in the first case, the "i" variable that each closure accesses, is the
same as the "i" used in the for loop which ends up equalling the # of
nodes.
in the second case, the "i" variable that each closure accesses, is a
private copy of the value of "i" at each pass of the for loop. The for-
loop's "i" is passed as an argument to the middle-level function, and
it's a copy of "i" that gets used in the closure. it would have been
clearer to write (for pedagogical purposes):
//Better example
var add_the_handlers = function(nodes){
var i;
for (i = 0; i < nodes.length; i
++) {
nodes[i].onclick =
function(icopy){
return function
(e){
alert
(icopy);
};
}(i);
}
};
// or even this:
var add_the_handlers = function(nodes){
var makeClosure = function(icopy)
{
return function(e) { alert(icopy); };
}
var i;
for (i = 0; i < nodes.length; i++) {
nodes[i].onclick = makeClosure(i);
}
};