数组中的innerHTML

时间:2015-12-08 15:48:56

标签: javascript html arrays innerhtml

我正在努力建立一个画廊。

我成功完成了除最后一个步骤之外的所有步骤,点击缩略图会将段落中的文本更改为我放入数组的另一个文本。

当我在for循环中时,我希望当我单击索引2的图像时显示索引2的文本。我似乎遵循了正确的语法,但段落仍显示“未定义”结果是。但是当我选择一个索引时,就像我点击的那个图片一样,我想显示索引3的文本,它可以工作。

这是我的简化代码,可以让我在点击段落时显示文字。如果你们不使用jQuery,那将是很棒的。谢谢大家!

<!DOCTYPE html>
<html>
<body>

<p class="demo">1</p>
<p class="demo">2</p>
<p class="demo">3</p>

    <script>
        var cars = ["Saab", "Volvo", "BMW"];
        var para = document.getElementsByClassName("demo");
        for (k=0;k<cars.length;k++){
          para[k].onclick=function(){
            this.innerHTML = cars[k];
          }
        }
    </script>

</body>
</html>

5 个答案:

答案 0 :(得分:4)

这是javascript的范围问题。你的变量k,注意你每次都增加它。当点击事件调用onclick时,无论您点击什么图像,k都会以3作为其值。

您可以尝试这种解决方法(请注意我稍微清理了一下代码)

<!DOCTYPE html>
<html>
<body>

<p class="demo">1</p>
<p class="demo">2</p>
<p class="demo">3</p>

    <script>
    var cars = ["Saab", "Volvo", "BMW"];
    var para = document.getElementsByClassName("demo");

    for (k = 0; k < cars.length; k++) {
      (function (index) {
        para[index].onclick = function() {
          this.innerHTML = cars[index];
        }
      }(k));
    }
</script>

</body>
</html>

在这种情况下,对于它所使用的每个值,单独的副本由k组成,该副本在函数内部可用作“索引”。

有关具体问题的详细信息,请参阅此帖:JavaScript closure inside loops – simple practical example

答案 1 :(得分:3)

使用关闭

<script>
  var cars = ["Saab", "Volvo", "BMW"];
  var para = document.getElementsByClassName("demo");
  for (var k = 0; k < cars.length; k++) {
    (function (k) {
      para[k].onclick = function () {
        this.innerHTML = cars[k];
      }
    }(k));
  }
</script>

小提琴:http://jsbin.com/zezuhitige

<强>原因:

该值始终是循环的最后一个值。因此,当点击发生时,您将始终获得k = 3,在点击时执行k值,即3。闭包通过在分配时执行值来防止这种情况。

答案 2 :(得分:0)

更灵活的做法是这样的:

<div id="container">
    <p class="demo" data-car="Saab">1</p>
    <p class="demo" data-car="Volvo">2</p>
    <p class="demo" data-car="BMW">3</p>
</div>

JS:

document.getElementById('container').onclick = function(e) {
    e = e || window.event;
    var target = e.srcElement || e.target;
    while( target != this && !target.className.match(/\bdemo\b/)) {
        target = target.parentNode;
    }
    if( target != this) {
        // target is now one of the .demo elements
        target.innerHTML = target.getAttribute("data-car");
    }
};

这会将数据本身放入其引用的元素中,并且只附加一个事件监听器而不是每个汽车一个 - 在更大的应用程序中,您拥有的事件处理程序越少越好!

答案 3 :(得分:0)

查看JS闭包并尝试以下内容:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures

document.addEventListener("DOMContentLoaded", function(event) { 
        var cars = ["Saab", "Volvo", "BMW"];
        var para = document.getElementsByClassName("demo");
        for (k=0;k<cars.length;k++){
          var clojureCar = cars[k];
          
          para[k].onclick=function(){
           
            this.innerHTML = clojureCar;
          }
        }
});
<!DOCTYPE html>
<html>
<body>

<p class="demo">1</p>
<p class="demo">2</p>
<p class="demo">3</p>

    <script>
        var cars = ["Saab", "Volvo", "BMW"];
        var para = document.getElementsByClassName("demo");
        for (k=0;k<cars.length;k++){
          para[k].onclick=function(){
            this.innerHTML = cars[k];
          }
        }
    </script>

</body>
</html>

答案 4 :(得分:0)

我认为添加像这样的事件监听器是一个很好的做法。并且因为你的click事件是在你的循环完成之后执行的所以它总是3是未定义的。

var cars = ["Saab", "Volvo", "BMW"];
var para = document.getElementsByClassName("demo");
for (k=0;k<cars.length;k++){
  var div = para[k];
  (function (i) {
    div.addEventListener('click', function() { this.innerHTML = cars[i]; });
  })(k);
}