Reputation: 16278
I have the following code:
for(var i = 0; i < nodelist.length; i++) {
var x = functionThatCreatesADivElement();
someElement.appendChild(x.getDiv()); // this works fine
nodelist[i].onclick = function() {
x.someFunction(); // this always refer to the last 'x' object
}
}
function functionThatCreatesADivElement() {
var div = document.createElement("div");
this.someFunction = function() {}
this.getDiv = function() {
return div;
}
return this;
}
the problem is that the execution of nodelist[0].onclick
is exactly the same as nodelist[4].onclick
(assuming that i = 4 is the last node).
I believe the references of the previously iterated are changing to point to the currently iterated element.
What is the proper way of doing this?
EDIT: Added some more code and changed the name of the function cause it was too confusing
Upvotes: 0
Views: 69
Reputation: 363
You have two problems. The first problem is that JavaScript variables don't have block scopes.
From MDN:
When you declare a variable outside of any function, it is called a global variable, because it is available to any other code in the current document. When you declare a variable within a function, it is called a local variable, because it is available only within that function.
JavaScript does not have block statement scope;
You aren't enclosing a the x
variable in a function, so all of your onclick callbacks are using the same x
variable, which point to whatever element is last in the loop since that will be the last one to have overwritten x
.
Doing this for your loop should work:
nodelist.forEach(function (nodeitem) {
var x = functionThatCreatesADivElement();
someElement.appendChild(x.getDiv());
nodeitem.onclick = function() {
x.someFunction();
}
});
The second problem is that your functionThatCreatesADivElement()
constructor function is not being called correctly. Use new functionThatCreatesADivElement()
since you are invoking a constructor function.
Upvotes: 1
Reputation: 16278
Solved. I had to use
var x = new functionThatCreatesADivElement();
function functionThatCreatesADivElement() {
var div = document.createElement("div");
this.someFunction = function() {}
this.getDiv = function() {
return div;
}
//return this; //Using new instead of returning this
}
Upvotes: 0