数组中的innerHTML [重复]

Posted

技术标签:

【中文标题】数组中的innerHTML [重复]【英文标题】:innerHTML in an array [duplicate] 【发布时间】:2016-03-13 14:59:53 【问题描述】:

我正在尝试制作画廊。

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

当我在 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>

【问题讨论】:

问题可能是索引k 没有在您的for 循环中的循环之间得到保留。您需要使用闭包。 【参考方案1】:

这是 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

【讨论】:

完美!谢谢。这就是我要找的!尽管我是初学者,但我会尝试解密此代码,并且我不太了解您将函数放在括号之间的部分。 是的!!!!我现在明白了!并且能够将它应用到我的实际项目中(我在问题中输入的小代码就像尝试该技术的简单演示一样。)我将在此评论中附加哪些代码(如果可能,否则我将通过电子邮件发送)如果有兴趣。再次感谢大家!!!【参考方案2】:

使用闭包

<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 = 3k的值是在点击的时候执行的,也就是3。闭包通过在赋值时正确执行值来防止这种情况发生。

【讨论】:

【参考方案3】:

更灵活的做法是这样的:

<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");
    
;

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

【讨论】:

【参考方案4】:

查看 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>

【讨论】:

【参考方案5】:

我认为添加这样的事件侦听器是一个好习惯。而且因为你的点击事件是在你的循环完成后执行的,所以它总是 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);

【讨论】:

以上是关于数组中的innerHTML [重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何阻止innerHtml表一遍又一遍地重复自己?

语法中的 innerHTML 错误不起作用;未捕获的 TypeError:无法设置 null 的属性(设置“innerHTML”)[重复]

将JSON结果限制在数组中[重复]

jQuery对象与DOM对象

在 innerHTML 中加载脚本 [重复]

为啥添加innerHTML后循环和数组停止工作?