1
for(let i = 0; i <= todosToday.length - 1; i++) {
  const a = document.createElement("a");

  a.addEventListener("click", function() {
    showFoundTodo(todosToday[i]);
  });

}

This works for Chrome but not for IE, specifically IE11. The instance of the array todosToday on i does not get passed when I attach the function showFoundTodo in the click event.

function showFoundTodo(todo) {
   console.log(todo);
}

This function prints out undefined thus making the argument unusable. On Chrome, it outputs to the object with no problems.

I checked and only in that instance does todosToday become unreadable. To zero in where the change occurse, every where else I'd do a console.log() and it prints out the object (before the for loop, inside, and after it). At first I thought it was the attachEvent compatibility but that was for earlier versions of IE and the function also gets called. Any help is greatly appreciated.

Rumba
  • 181
  • 1
  • 2
  • 9
  • 1
    Possible duplicate of [JavaScript closure inside loops – simple practical example](https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – Ivar Jan 04 '18 at 17:39
  • 1
    Tip: for(let i = 0; i <= todosToday.length - 1; i++) for(let i = 0; i < todosToday.length; i++) -- saves you some typing and (some) processing time – Tony Duffill Jan 04 '18 at 17:41

1 Answers1

2

The loop variable i is not in the scope by the time the listener fires. The simple way to fix it is to move it to the outer scope:

var i;
for(i = 0; i <= todosToday.length - 1; i++) {

The way I generally preferred when modifying the DOM directly was to add the object reference to the element.

var todosToday = [ 'Wake up.', 'Kiss my wife.', 'Take a shower.' ];

for(var i = 0; i <= todosToday.length - 1; i++) {
  var a = document.createElement("a");
  a.innerText = todosToday[i];
  a.todo      = todosToday[i];

  a.addEventListener("click", function() {
    showFoundTodo(this.todo);
  });
  
  var div = document.createElement('div')
  div.appendChild(a);
  document.body.appendChild(div);
}

function showFoundTodo(todo) {
   console.log(todo);
}

Note: You have a problem in all IE versions, BTW. addEventListener is not supported before IE 9 and let and const are not supported before IE 11.

sthames42
  • 888
  • 8
  • 19
  • thank you! I didn't think it was a scoping issue since it worked on Chrome. – Rumba Jan 04 '18 at 19:20
  • It's a scoping issue because Chrome executed the listener within the scope of the `for` loop and IE executed it within the scope of the document. BTW, the Chrome way is correct so it's a bug in IE. Go figure! – sthames42 Jan 04 '18 at 21:34