Javascript. Onclick Returns Always The Same Object
30m + 15s
Solution 1:
Try this
var selectionTabs = document.getElementsByClassName("game-selection-tab");
for(var i = 0; i < selectionTabs.length; i++){
(function (index) {
var tab = selectionTabs[index];
var content = tab.getElementsByTagName("h2");
tab.onclick = function(){
console.log(content[0].textContent);
}
})(i);
}
The thing is by the time your event attaches to the actual DOM element the for loop execution is complete and the value of i is the max value that it can reach. Hence, isolating the same in a function like this works. The function stores the value of i
or in this case index
as the original value that you expect.
Solution 2:
Replace
var i = 0
by
let i = 0
and you're done.
A detailed explanation is here.
I'll quote my answer for your understanding below.
Cause of the problem: lack of understanding scope
Check this example to understand the problem:
var
creates function scope
var funcs = []
for (var i = 0; i < 10; i++) {
funcs.push(function() {
console.log(i)
})
}
funcs.forEach(function(func) {
func()
})
While you might expect this forEach
loop to result in number 0
to 9
being printed, instead you get ten times 10
. The cause of this is the variable i
being declared using var
keyword, which creates a function scope
that leads to each function
in funcs
holding a reference to the samei
variable. At the time the forEach
loop is executed, the previous for
-loop has ended and i
holds 10 (9++ from the last iteration).
Compare how ES6's let
, which creates block scope
instead of function scope
, behaves in this regard:
let
(ES6 or officially ES2015) creates block scope
:
var funcs = []
for (let i = 0; i < 10; i++) {
funcs.push(function() {
console.log(i)
})
}
funcs.forEach(function(func) {
func()
})
Because let
creates block scope
, each iteration of the for
loop has its "own" variable i
.
ES5 solution using an IIFE
wrapper
If you need an ES5 solution, an IIFE (immediately invoked function expression) wrapper would be the way to go:
var funcs = []
for (var i = 0; i < 10; i++) {
funcs.push((function(value) {
returnfunction() {
console.log(value)
}
}(i)))
}
funcs.forEach(function(func) {
func()
})
Here, i
is passed as a parameter to each function which stores its own copy value
.
The same is true for for..in
loops:
var funcs = [],
obj = {
first: "first",
last: "last",
always: "always"
}
for (var key in obj) {
funcs.push(function() {
console.log(key)
})
}
funcs.forEach(function(func) { // outputs: "always", "always", "always"func()
})
Again, all functions in funcs
hold the reference
to the same key
because var key
creates a function scope that lives outside of the for..in
loop. And again, let
produces the result you'd probably rather expect:
var funcs = [],
obj = {
first: "first",
last: "last",
always: "always"
}
for (let key in obj) {
funcs.push(function() {
console.log(key)
})
}
funcs.forEach(function(func) {
func()
})
Also compare the excellent (!) book
Nicholas C. Zakas: "Understanding ES6", no starch press, p. 8-9.
from which the examples were taken.
Solution 3:
It's showing always the same value because you are setting content outside of the onclick
function. After the for loop, content
points to the last h2.
Move the content definition inside the onclick
function.
tab.onclick = function(){
var content = this.getElementsByTagName("h2");
console.log(content[0].textContent);
}
Solution 4:
Can you try the solution below.
var selectionTabs = document.getElementsByClassName("game-selection-tab");
Object.keys(selectionTabs).forEach((data, index) => {
var context = selectionTabs[data].getElementsByTagName("h2")[0].textContent;
selectionTabs[data].onclick = function () {
console.log(context)
}
})
Solution 5:
Try this simple solution:
var els = document.getElementsByClassName('game-selection-tab');
var index = 0;
functiongetText() {
alert(this.innerText || this.textContent);
}
for (; index < els.length; index++) {
els[index].onclick = getText;
}
<divclass="game-selection-tab"><h2>30m + 15s</h2></div><divclass="game-selection-tab"><h2>60m + 0s</h2></div><divclass="game-selection-tab"><h2>Custom</h2></div>
Post a Comment for "Javascript. Onclick Returns Always The Same Object"