javascript - Why is the loop assigning a reference of the last index element to? -
this question has answer here:
i want add event listener of tags, each passing reference itself parameter when triggered. here function wrote:
function validatedigitsfeature() { // add event listeners input tags // array of input tags var inputtags = document.getelementsbyclassname('validateinput'); var tagid; // loop through them, adding onkeypress event listener each 1 (var = 0; < inputtags.length; i++) { // give each input element id tagid = inputtags[i].id = 'input_id_' + i; inputtags[i].addeventlistener('keyup', function(){isnumberordot(event, tagid);}, false); } }
basically function should following:
- store input tags specified classname in array
- loop through array, adding id each tag and
- adding
onkeyup
event listenerisnumberordot(event, tagid)
handler.
problem
the onkeyup event added, handlers of each 1 always referencing tagid
of last element of array.
question
what wrong code/logic? , how can fixed?
note
sure problem related javascript closure in loops, while question have more general answer, specific event listeners being used. more advanced developers, might easy apply general solution problem. me other solutions still didn't provide full explanation or worked.
thank in advance.
because actual event occurs sometime in future after for
loop has finished running , index @ last value , local variables in function tagid
@ last value. need create sort of closure preserves value of i
or tagid
uniquely each event handler each have access own value.
there several different ways that, involve passing i
value function each event handler.
here's 1 using iife (immediately invoked function expression):
function validatedigitsfeature() { // add event listeners input tags // array of input tags var inputtags = document.getelementsbyclassname('validateinput'); // loop through them, adding onkeypress event listener each 1 (var = 0; < inputtags.length; i++) { // give each input element id (function() { // creates unique function context each event handler // value of tagid unique each event handler var tagid = inputtags[i].id = 'input_id_' + i; inputtags[i].addeventlistener('keyup', function(){isnumberordot(event, tagid);}, false); })(); } }
a little more common way pass index for
loop closure , calculation based on inside event handler (though either method works fine) this:
function validatedigitsfeature() { // add event listeners input tags // array of input tags var inputtags = document.getelementsbyclassname('validateinput'); // loop through them, adding onkeypress event listener each 1 (var = 0; < inputtags.length; i++) { // give each input element id (function(index) { // passes `for` loop index function closure // uniquely preserved each event handler inputtags[index].addeventlistener('keyup', function(){ isnumberordot(event, inputtags[index].id = 'input_id_' + index); }, false); })(i); } }
Comments
Post a Comment