我在html文档中以下列方式获得了16个相同类名的div
<div class="game-selection-tab">
<h2>30m + 15s</h2>
</div>
<div class="game-selection-tab">
<h2>60m + 0s</h2>
</div>
<div class="game-selection-tab">
<h2>Custom</h2>
</div>
我想创建一个从特定div返回h2文本内容的onclick方法。我尝试使用以下javascript代码来解决这个问题。
var selectionTabs = document.getElementsByClassName("game-selection-tab");
for(var i = 0; i < selectionTabs.length; i++){
var tab = selectionTabs[i];
var content = tab.getElementsByTagName("h2");
tab.onclick = function(){
console.log(content[0].textContent);
}
}
问题是:无论我点击哪个div,程序总是从最后一个div返回h2文本内容(在本例中为“custom”)。
答案 0 :(得分:2)
试试这个
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);
}
当事件附加到实际的DOM元素时,for循环执行完成,i的值是它可以达到的最大值。因此,在像这样的函数中隔离相同的工作。该函数将i
或index
的值存储为您期望的原始值。
答案 1 :(得分:2)
替换
var i = 0
通过
let i = 0
你已经完成了。
详细解释为here。
我将在下面引用您的答案以供您理解。
scope
选中此示例以了解问题:
var
创建function scope
var funcs = []
for (var i = 0; i < 10; i++) {
funcs.push(function() {
console.log(i)
})
}
funcs.forEach(function(func) {
func()
})
&#13;
虽然您可能希望此forEach
循环导致正在打印0
到9
,但您会获得10次10
。造成这种情况的原因是使用i
关键字声明变量var
,这会创建function scope
,导致function
中的每个funcs
持有引用到相同的 i
变量。在执行forEach
循环时,先前的for
- 循环已结束且i
保持10(从上次迭代开始的9 ++)。
比较创建let
而不是block scope
的ES6&#39; function scope
在这方面的行为:
let
(ES6或正式 ES2015 )创建block scope
:
var funcs = []
for (let i = 0; i < 10; i++) {
funcs.push(function() {
console.log(i)
})
}
funcs.forEach(function(func) {
func()
})
&#13;
由于let
创建block scope
,for
循环的每次迭代都有其自己的&#34;变量i
。
IIFE
包装器如果你需要一个ES5解决方案,一个IIFE( i 立即 i nvoked f unction e xpression)包装将是要走的路:
var funcs = []
for (var i = 0; i < 10; i++) {
funcs.push((function(value) {
return function() {
console.log(value)
}
}(i)))
}
funcs.forEach(function(func) {
func()
})
&#13;
此处,i
作为参数传递给存储其自己的副本value
的每个函数。
for..in
循环也是如此:
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()
})
&#13;
同样,funcs
中的所有函数都将reference
保持为相同的key
,因为var key
创建了一个位于for..in
循环之外的函数作用域。同样,let
会产生您可能更期待的结果:
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()
})
&#13;
还要比较优秀的(!)书
Nicholas C. Zakas: "Understanding ES6",没有淀粉压榨,p。 8-9。
从中获取了这些例子。
答案 2 :(得分:1)
它显示的值始终相同,因为您在onclick
函数之外设置了内容。在for循环之后,content
指向最后一个h2。
将内容定义移到onclick
函数中。
tab.onclick = function(){
var content = this.getElementsByTagName("h2");
console.log(content[0].textContent);
}
答案 3 :(得分:0)
您可以尝试以下解决方案。
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)
}
})
答案 4 :(得分:0)
尝试这个简单的解决方案:
var els = document.getElementsByClassName('game-selection-tab');
var index = 0;
function getText() {
alert(this.innerText || this.textContent);
}
for (; index < els.length; index++) {
els[index].onclick = getText;
}
<div class="game-selection-tab">
<h2>30m + 15s</h2>
</div>
<div class="game-selection-tab">
<h2>60m + 0s</h2>
</div>
<div class="game-selection-tab">
<h2>Custom</h2>
</div>
答案 5 :(得分:0)
假设您不想更改HTML以在每个h2上包含“onclick”事件,此代码可能会对您有所帮助:
document.addEventListener('click', function(e) {
e = e || window.event;
var target = e.target || e.srcElement,
text = target.textContent || text.innerText;
console.log(text);
}, false);
EDIT 如果你想更具体,只从你的h2获取内容,你可以使用:
h2s = document.getElementsByTagName('h2');
for (var i = 0; i < h2s.length; i++) {
h2s[i].addEventListener('click', redirect, false);
}
function redirect(e) {
var target = e.target || e.srcElement;
var text = target.textContent || text.innerText;
console.log(text);
}