1

I have a preloaded page and I am trying to add onclick event to all the nodes with a specific class name. But the function in the onclick should use the element node in it.

var elemArr=document.getElementsByClassName('ABC');

    for(var i=0;i<elemArr.length;i++){

        elemArr[i].onclick = function()
        {
            console.log(elemArr[i]);  // This is being returned as undefined
            // How can I use elemArr[i] here 
        };
    }

I tried

for(var i=0;i<elemArr.length;i++){

    printObj=elemArr[i];
    elemArr[i].onclick = function()
    {
        console.log(printObj);
        var newObject = jQuery.extend(true, {}, printObj);
        console.log(newObject );
    };
}

but didn't work.I feel the above won't work anyway. How do I solve this problem..?

21
  • You have to use JavaScript Closures: developer.mozilla.org/en/docs/Web/JavaScript/Guide/Closures Commented Dec 11, 2014 at 15:00
  • All your handlers are sharing the same i variable, which by the time your handler is called, will have the value of elemArr.length See the linked question. Simplest solution for(var i=0;i<elemArr.length;i++){ elemArr[i].onclick = (function(index) { return function(e){ console.log(elemArr[index]) } })(i); Commented Dec 11, 2014 at 15:02
  • 1
    @KarlenKishmiryan The OP is already using closures ;) The problem is that the OP is sharing a closure Commented Dec 11, 2014 at 15:06
  • For consistency in code, when using jQuery, use it ;) Commented Dec 11, 2014 at 15:07
  • ... and you would automatically avoid closure problem with jQuery. Commented Dec 11, 2014 at 15:08

1 Answer 1

7

You should wrap your code inside of loop with a function so that a new copy of i is created for each of your event handlers, like this.

var elems = document.getElementsByClassName('elem');

if (elems.length) {
  for (var i = 0, l = elems.length; i < l; i++) {
    (function(i) {
      elems[i].onclick = function() {
        alert('Element #' + i);
      }
    })(i);
  }
}

// Could also use bind for slighlty cleaner code
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

for (var i = 0, l = elems.length; i < l; i++) {
  elems[i].onmousedown = (function(index, e) {
    console.log('MouseDown - Element  #' + index);
  }).bind(elems[i], i);
}
<div class="elem">Elem #1</div>
<div class="elem">Elem #2</div>
<div class="elem">Elem #3</div>

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.