If you use JavaScript to put some dynamic to your websites you often have the problem to pass parameters to the event-function. One solution is to use closures. With the element of closures you can access outer variables from inner inline functions.
One example would be:
1 2 3 4 5 6 | var ps = document.getElementyByTagName("p"); for(var i = 0; i < ps .length; i++) { ps[i].onclick = function (event) { window.alert("you clicked the element with index "+i); } } |
You would assume that the first Element would say “…element with index 0” and the second “…element with index 1”. Unfortunaly all p-tags will say “…element with index 10” if you have 10 tags on the site. The reason is that i is modified later and is directly referenced to the inner-function. So you have to modify the code as follows:
1 2 3 4 5 6 7 8 9 | var ps = document.getElementyByTagName("p"); for(var i = 0; i < ps .length; i++) { ps[i].onclick = function(param) { return function (event) { window.alert("you clicked the element with index "+param); } }(i); } } |
Here I wrapped the event with a outer function which provides the parameter (i) as a new reference. So the first p-tag will say “…element with index 0”, the second “…element with index 1” and so on.
But there exists one unfortunately trap. You will reference the “ps”-Variable with your event-function and this parameter could not be removed by the garbage collector. So we have to modify the code:
1 2 3 4 5 6 7 8 9 | function generateevent(param) { return function (event) { window.alert("you clicked the element with index "+param); } } var ps = document.getElementyByTagName("p"); for(var i = 0; i < ps .length; i++) { ps[i].onclick = generateevent(param); } |
A also perfect other solution is provided by some JavaScript-frameworks like JQuery. Here you can use the event method “bind” or the data method “data” to bind specific data to an function:
1 2 3 4 5 6 7 8 | function event(param) { window.alert("you clicked the element with index "+param.data); } var ps = $("p"); for(var i = 0; i < ps .length; i++) { $(ps[i]).bind("click", i, event); } |