开发者问题收集

无法读取未定义的属性“removeClass”

2016-06-13
3958

我试图制作自动幻灯片,但是这个消息一直弹出,我不明白为什么。

HTML:

<section id="slideshow">
    <div class="auto-slideshow">
        <img src="img/pic1.jpg" alt="" class="slide show">
        <img src="img/pic2.jpg" alt="" class="slide hide">
        <img src="img/pic3.jpg" alt="" class="slide hide">
    </div>
</section>

“显示”和“隐藏”类分别将显示设置为“阻止”和“无”。

JavaScript:

autoSlideshow();

var mySlides = $('#slideshow .slide');
var slides = [];
mySlides.each(function () {
    slides.push($(this));
});

function autoSlideshow() {
    var index;
    var next;

    mySlides.each(function () {
        if ($(this).hasClass('show')) {
            index = $(this).index();
            next = index+1;

            $(this).removeClass('show').addClass('hide');
            slides[next].removeClass('hide').addClass('show');

            console.log('The index is: '+index);
            console.log('The next one is: '+next);
        };
    });
    setInterval(autoSlideshow, 3000);
};

任何建议或更正都非常感谢。

3个回答

首先,您应该在定义 mySlides 后调用 autoSlideshow()。然后在超出范围时重新初始化 next 的值。调用 autoSlideshow 的最佳方式是将其从方法中取出:

function autoSlideshow() {
    var index;
    var next;

    mySlides.each(function() {
        if ($(this).hasClass('show')) {
            index = $(this).index();
            next = index + 1;
            next = next >= mySlides.length ? 0 : next;

            //DO WHAT YOU WERE DOING
        };
    });

};

setInterval(autoSlideshow, 3000);
Nafiul Islam
2016-06-13

非常接近,只有几件事。

您正在迭代所有幻灯片,更新所有幻灯片

function autoSlideshow() {
  mySlides.each(function () { //code snipped }
}

这是循环遍历所有幻灯片,每次迭代都会将下一张幻灯片设置为可见,因此当循环结束时,您将回到开始的位置。

每次调用该函数时,您都会添加一个新计时器

function autoSlideshow() {
  //code snipped
  setInterval(autoSlideshow, 3000);
};

每次调用此函数时,都会添加另一个再次调用它的计时器。您只需使用 setInterval() 一次。

CSS 更新 将类设置为 display: none; 要求您在每次更新幻灯片时删除该类。更好的方法是将 display: none; 作为幻灯片中图像的 默认 属性。然后,您只需添加 show 类,而不必担心删除 hide 类。

更新的代码:

JavaScript

$(document).ready(function() { //wait until the DOM is ready...
  var mySlides = $('#slideshow .slide');
  var slides = [];
  var index = 0;

  mySlides.each(function () {
    slides.push($(this));
  });

  function autoSlideshow() {
    index++;
    var nextSlide = index%slides.length;  //the mod function makes sure you stay within the bounds of the array
    $('.show').removeClass('show'); //remove the show class from the existing slide
    slides[nextSlide].addClass('show'); //add the show class to the next slide
  };
  setInterval(autoSlideshow, 3000);
})

HTML

<section id="slideshow">
  <div class="auto-slideshow">
    <img src="https://unsplash.it/200/300" alt="" class="slide show">
    <img src="https://unsplash.it/200/301" alt="" class="slide">
    <img src="https://unsplash.it/200/302" alt="" class="slide">
  </div>
</section>

CSS

#slideshow img { display: none; }
#slideshow img.show { display: block; }

在此 JS Fiddle 中查看其工作情况: https://jsfiddle.net/igor_9000/9mhujoa9/

希望对您有所帮助!

ak_
2016-06-13

使用您提供的 HTML,您可以假设 slides 变量中有 3 个元素。现在,在迭代 mySlides 时,您将索引分配给一个变量,并使用该值 + 1 来访问 slides 数组的一个元素。如果您当前位于 mySlides 数组的第 3 个项目上,会发生什么情况?索引将为 2,下一个将设置为 3。由于 slides 只有 3 个值,因此只能到达 slides[2],代码正在尝试访问当前未定义的幻灯片索引。

user1124164
2016-06-13