[英]PHP not decoding a JSON object created with Javascript. Error ALWAYS returns 4
[英]Javascript. Onclick returns always the same object
我以以下方式在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>
我想创建onclick方法,该方法从特定的div返回h2文本内容。 我试图通过使用以下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”)。
尝试这个
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
为您期望的原始值。
更换
var i = 0
通过
let i = 0
到此为止。
详细说明在这里 。
我将在下面引用我的答案以供您理解。
scope
检查此示例以了解问题:
var
创建function scope
var funcs = [] for (var i = 0; i < 10; i++) { funcs.push(function() { console.log(i) }) } funcs.forEach(function(func) { func() })
尽管您可能希望此forEach
循环导致打印0
到9
,但您会得到10乘以10
。 原因是使用var
关键字声明了变量i
,该变量创建了一个function scope
,该function scope
导致funcs
每个function
持有对相同 i
变量的引用 。 在执行forEach
循环时,前一个for
循环已结束,并且i
持有10(最后一次迭代的9 ++)。
比较一下ES6的let
,它创建block scope
而不是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() })
因为let
创建了block scope
,所以for
循环的每个迭代都有其“自己的”变量i
。
IIFE
包装器的ES5解决方案 如果你需要一个ES5液,IIFE( 我 mmediately 我 nvoked˚F结Ë上的表达)的包装将是要走的路:
var funcs = [] for (var i = 0; i < 10; i++) { funcs.push((function(value) { return function() { console.log(value) } }(i))) } funcs.forEach(function(func) { func() })
在这里, 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() })
同样,在所有功能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() })
同时比较优秀的(!)书
尼古拉斯·扎卡斯(Nicholas C. Zakas):“ Understanding ES6” (不理解ES6) ,第8页。 8-9。
以此为例。
它始终显示相同的值,因为您是在onclick
函数之外设置内容的。 在for循环之后, content
指向最后一个h2。
将内容定义onclick
函数中。
tab.onclick = function(){
var content = this.getElementsByTagName("h2");
console.log(content[0].textContent);
}
您可以尝试以下解决方案吗?
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)
}
})
试试这个简单的解决方案:
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>
假设您不想更改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);
编辑如果您想更具体一些,并且仅从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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.