Creating closures in loops

var list2 = document.querySelectorAll(‘.list2 li’);
for (var i = 0; i < list2.length; i++) {
list2[i].addEventListener(‘click’, function () {
console.log(‘My index:’, i);
}, false);
}

Inspect the output in the console from clicking an item from “.list2”, each index is the same and also fix the problem to log the correct index.

Hi himanshu_chawla welcome to the forum

The “Creating closures in loops: A common mistake” section should help some.

Thanks a lot @Mittineague but I am still unable to find the problem … Can you just locate the problem . Help is appreciated and thanks in advance.

The problem is that after the loop to add all the listeners has run i is equal to list2.length so no matter which of the event listeners is run that is the value that gets logged.

To fix it you need to create a closure so that the console.log call can display the value that i had at the time the event listener was added rather than the value it has at the time the listener is run.

var list2 = document.querySelectorAll(‘.list2 li’);
for (var i = 0; i < list2.length; i++) {
list2[i].addEventListener(‘click’, function() {
}, false);
console.log(‘My index:’, i);
}

Thanks @felgall … You made ita and thanks a lot … Just Completed the task .

Thank You

Nope, that’s not quite right. Here’s one way to create a closure around the addEventListener part of the code that keeps the correct i value.

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title></title>
</head>
<body>

<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
</ul>

<script>
var items = document.querySelectorAll('li');
for (var i = 0; i < items.length; i++) {

  (function(i) {

    items[i].addEventListener('click', function() {
      console.log('My index:', i);
    }, false);

  })(i)

}
</script>

</body>
</html>

Alternatively you can pull it out into a function

var items = document.querySelectorAll('li');
var createClickHander = function(item) {
  item.addEventListener('click', function() {
    console.log('My index:', i);
  }, false);
}
for (var i = 0; i < items.length; i++) {
  createClickHander(items[i])
}
1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.