代码:
<body>
<div class="con">
<button class="tabs"> HTM </button>
<button class="tabs"> JS </button>
<button class="tabs"> CSS </button>
</div>
<div class="data"> </div>
<script>
var bu = document.getElementsByClassName("tabs");
var contents=["HTML", "js" , "css"];
for(var i=0; i<bu.length; i++){
alert(contents[i]);
bu[i].onclick=function(){
alert(contents[i]);
document.getElementsByClassName("data").innerHTML = content[i];
}
}
</script>
<body>
在上面的程序中,for语句旁边的alert函数正确执行。但是,它在“功能”中不起作用。我是什么 我认为,“函数”中的语句都只与按钮对象有关。这样对吗?如果是的话,如何访问 “功能”中的数组?
答案 0 :(得分:2)
使用
Closures
以便返回的函数将记住创建它的环境。
当事件在loop
中注册时,在调用click-handler
时,i
的值为3
且{{1}中没有元素索引为array
,返回3
。
另请注意,getElementsByClassName
返回undefined
,其中没有属性collection(array-like object)
,使用innerHTML
索引来抓取元素或使用querySelector
0th
&#13;
var bu = document.getElementsByClassName("tabs");
var contents = ["HTML", "js", "css"];
for (var i = 0; i < bu.length; i++) {
bu[i].onclick = (function(i) {
return function() {
document.querySelector(".data").innerHTML = contents[i]; //correct typo here
}
})(i);
}
&#13;
<div class="con">
<button class="tabs">HTM</button>
<button class="tabs">JS</button>
<button class="tabs">CSS</button>
</div>
<div class="data"></div>
&#13;
var bu = document.getElementsByClassName("tabs");
var contents = ["HTML", "js", "css"];
[].forEach.call(bu, function(item, index) {
item.onclick = function() {
document.querySelector(".data").innerHTML = contents[index];
}
});
&#13;
答案 1 :(得分:1)
在单击事件发生时,值将是数组的长度,因为循环增量i
。因此,您需要使用功能级变量,该变量在迭代中保存i
的值。
document.getElementsByClassName()
返回一个类似live HTMLCollection的数组,您需要获取一个元素来更新innerHTML
属性。
您可以在新浏览器中使用let
,它为变量提供块级范围。
<body>
<div class="con">
<button class="tabs">HTM</button>
<button class="tabs">JS</button>
<button class="tabs">CSS</button>
</div>
<div class="data"></div>
<script>
var bu = document.getElementsByClassName("tabs");
var contents = ["HTML", "js", "css"];
for (let i = 0; i < bu.length; i++) {
alert(contents[i]);
bu[i].onclick = function() {
alert(contents[i]);
document.getElementsByClassName("data")[0].innerHTML = contents[i];
}
}
</script>
<body>
<小时/> 或使用closure并传递
i
作为参数
<body>
<div class="con">
<button class="tabs">HTM</button>
<button class="tabs">JS</button>
<button class="tabs">CSS</button>
</div>
<div class="data"></div>
<script>
var bu = document.getElementsByClassName("tabs");
var contents = ["HTML", "js", "css"];
for (let i = 0; i < bu.length; i++) {
alert(contents[i]);
(function(i) {
bu[i].onclick = function() {
alert(contents[i]);
document.getElementsByClassName("data")[0].innerHTML = contents[i];
}
})(i)
}
</script>
<body>
答案 2 :(得分:0)
这是由于闭包变量递增而导致闭包变量无效的回调的典型示例。即使在第一次点击按钮并且i
没有返回任何内容之前,您的变量contents[i]
也会增加到3。将您的函数更改为具有 IIFE ,如下所示,为变量i提供词法范围:
for(var i=0; i<bu.length; i++){
alert(contents[i]);
(function (index) {
bu[index].onclick=function(){
alert(contents[index]);
console.log(index);
document.getElementsByClassName("data")[0].innerHTML = contents[index];
}
})(i);
}
这将在每个按钮点击的词法范围内修改索引变量。
您的代码中还有一个拼写错误,您使用content[i]
代替contents[i]
我在这里创建了一个有效的JSBIn:https://jsbin.com/fasicu/2/edit?html,js,console,output
<强>更新强>
Document.getElementsByClassName()
返回具有所有给定类名的所有子元素的类数组对象。在文档对象上调用时,将搜索完整的文档,包括根节点。
因此,为了访问单个元素,您需要使用索引0
请参阅MDN了解详情:https://developer.mozilla.org/en/docs/Web/API/Document/getElementsByClassName