【问题标题】:Iterating through an array of divs遍历 div 数组
【发布时间】:2015-12-03 05:55:39
【问题描述】:

我仍然是 javascript 的新手,我已经学习了几个月的概念,这是我第一次尝试它。

我正在尝试使用 css3 和 Javascript(无 Jquery)创建轮播

控制台不断报错。

未捕获的类型错误:无法读取未定义的属性display

以下是我的html和javascript代码

var slideShow = document.querySelectorAll('.inside');

for (var i = 0; i < slideShow.length; i++) {
  setTimeout(function() {
    slideShow[i].display.style = 'inline-block';
  }, 2000)
}
<div class="inside">
  <div class="inner1">
    <h1>This is Inner div 1</h1>
  </div>
  <div class="inner2">
    <h1>This is Inner div2</h1>
  </div>
  <div class="inner3">
    <h1>This is Inner div3</h1>
  </div>
  <div class="inner4">
    <h1>This is Inner div4</h1>
  </div>
</div>

【问题讨论】:

    标签: javascript html css


    【解决方案1】:

    除了displaystyle顺序不对之外,问题在于setTimeout回调函数执行的时候,for循环已经结束,i等于nodeList 的长度(并且由于最后一个元素的索引比 nodeList 的长度小一,因此抛出错误)。

    您可以在IIFE 中捕获i 的值:

    Example Here

    var slideShow = document.querySelectorAll('.inside');
    
    for (var i = 0; i < slideShow.length; i++) {
      (function (i) {
        setTimeout(function () {
          slideShow[i].style.display = 'inline-block';
        }, 2000 * (i + 1));
      })(i);
    }
    

    或者你可以使用.forEach() method:

    Example Here

    var slideShow = document.querySelectorAll('.inside');
    
    Array.prototype.forEach.call(slideShow, function (el, i) {
      setTimeout(function () {
        el.style.display = 'inline-block';
      }, 2000 * (i + 1));
    });
    

    或者,您可以只使用setInterval

    Example Here

    var slideShow = document.querySelectorAll('.inside');
    var i = 0;
    var interval = setInterval(function () {
      if (i < slideShow.length) {
        slideShow[i].style.display = 'inline-block';
        i++;
      } else {
        clearInterval(interval);
      }
    }, 2000);
    

    【讨论】:

    • 是的,而且看起来OP想要逐渐改变显示,而不是一次全部,所以你可以将固定的2000更改为2000 * (i + 1)
    • 没有错误抛出,但它不会改变 div 的样式,其他三个仍然隐藏,我认为我真的应该将 css 发布到
    • @Veritas 我更新了我的答案并发布了 3 个示例。希望这会有所帮助。
    【解决方案2】:

    您的 displaystyle 顺序错误。

    应该是slideShow[i].style.display='inline-block';

    此外,slideShow 只是一个长度为 1 的类数组对象:它包含 div .inner 但不包含其子元素。如果要遍历子元素,请使用

    var slideShow = document.querySelector('.inside').children;
    

    编辑: 正如 Josh 在单独的答案中指出的那样,在 for 循环中使用 setTimeout 时还有另一个问题。到超时内的函数执行时,i 将是 4,这会给你一个未定义的值。

    如果您坚持使用 for 循环,您也可以使用 forEach 方法执行此操作。但是,slideShow 在技术上并不是一个数组,而是一个“类数组对象”,因此它没有自己的forEach 方法。相反,您必须像这样调用 Array.prototype 方法:

    [].forEach.call(slideShow, function(item) {
        setTimeout(function() {
            item.style.display = 'inline-block';
        }, 2000);
    });
    

    【讨论】:

    • 我也试过了,它说“未捕获的类型错误:无法读取未定义的属性'样式'”
    • @Veritas 那是因为 document.querySelectorAll('.inside') 返回一个长度为 1 的数组:只有一个类为 .inside 的 div。您似乎想要的是该 div 中的元素数组。在这种情况下,您应该使用var slideShow = document.querySelector('.inside').children;
    • 我应该使用 forEach 吗?
    • 你可以使用forEach,但是JavaScript的一个有趣的怪癖是slideShow不是一个实际的数组;相反,它是一个“类似数组的对象”。这意味着它没有forEach 方法。如果你很聪明,你仍然可以使用它。我更新了上面的答案,以展示您如何做到这一点。
    • 我最近浏览了这个,我注意到一年零七个月前你试图帮助我多少,我只想说声谢谢,从那时起我在使用 js 时学到了很多东西现在每天现在。只是想说声谢谢...因为这个问题和你的回答让我对继续使用 JS 更感兴趣
    【解决方案3】:

    问题是您只选择了 div.inside 而它没有返回 div.inner 如果您想选择所有 .inner,请尝试此操作 将 class="inside" 更改为 id="inside" 并复制此 js

    var slideShow=document.getElementById("inside").querySelectorAll('div');
    slideShow[1].style.backgroundColor  = "red";
    for (var i=0; i<slideShow.length; i++){
    
        setTimeout(myFun(i), 2000)
    
    }
    
    function myFun(i ){slideShow[i].style.display  = "inline-block";}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-31
      相关资源
      最近更新 更多