Variable holds last value when added to multiple event listeners


This was a problem I faced when I had to add event listeners to elements created in a loop such that the elements should alert the value of var i in the event onClick.

To explain this problem properly I will show a practical example. In this case I'm trying to create list-items that on the event of a click will show it's unique row id.

The most common approach would be to code something like below:
<script type="text/javascript">
function my_func()
{
var ol=document.createElement("ol");
document.body.appendChild(ol);
 
	for(var i=1; i<11; i++)
	{
	var li=document.createElement("li");
	li.innerHTML="This is a list item";
	li.onclick=function(onClick){alert(i);}
	ol.appendChild(li);
	}
}
my_func();
</script>
If you try this out in your browser, you will find that the value 11 is alerted irrespective of the list-item that was clicked.
To fix this we need to make a workaround using DOM and the title attribute of the list-item.

Workaround

The trick is let an attribute of the element hold the value, and using the onClick event to alert the title of the element! Example:



The code would then look like this:

<script type="text/javascript">
function my_func()
{
var ol=document.createElement("ol");
document.body.appendChild(ol);
 
	for(var i=1; i<11; i++)
	{
	var li=document.createElement("li");
	li.innerHTML="This is a list item";
	li.setAttribute("title",i);//note this
	li.onclick=function(onClick){alert(this.title);}//note this
	ol.appendChild(li);
	}
}
my_func();
</script>

This technique can also be used to pass more variables, for example unique id and category id.
You would then use the Javascript split function to explode the title string by a special character.
Using the character * would require you to split the title attribute with element.split('*')



Posted by James on 2009-05-01 in the category " javascript "