Javascript

时间:2016-06-02 06:19:56

标签: javascript arrays function

代码:

<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函数正确执行。但是,它在“功能”中不起作用。我是什么 我认为,“函数”中的语句都只与按钮对象有关。这样对吗?如果是的话,如何访问 “功能”中的数组?

3 个答案:

答案 0 :(得分:2)

  

使用Closures以便返回的函数将记住创建它的环境。

当事件在loop中注册时,在调用click-handler时,i的值为3且{{1}中没有元素索引为array,返回3

另请注意,getElementsByClassName返回undefined,其中没有属性collection(array-like object),使用innerHTML索引来抓取元素或使用querySelector

&#13;
&#13;
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;
&#13;
&#13;

或使用Array#forEach

&#13;
&#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;
&#13;
&#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