2016-06-13 136 views
2

我想做一个自动的幻灯片,但这个消息不断弹出,我不明白为什么。无法读取属性'removeClass'的undefined

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

因为未来可能是不确定的,如果它是在幻灯片 – Li357

+0

量这可能是滑梯[下一页]是一个JavaScript对象,而不是jQuery对象。 –

+0

您可能还想使用'setTimeout'或者在函数外执行'setInterval'。 – putvande

回答

0

非常接近,只是一些事情。

你遍历所有的幻灯片,更新所有的人都

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

这是遍历所有的幻灯片,每个迭代将下一张幻灯片可见,因此当循环完成你”马上回到你开始的地方。

你每次调用该函数

​​

每次调用该函数时添加新的计时器,又添加了另一个计时器再次调用它。您只需要使用setInterval()一次。

CSS更新 有一类设置为display: none;要求你每次更新的幻灯片时间删除类。更好的方法是让display: none;成为幻灯片中图像的默认属性。然后,您只需添加show类,而不必担心删除隐藏类。

更新的代码:

的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工作小提琴:https://jsfiddle.net/igor_9000/9mhujoa9/

希望帮助!

0

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

1

首先,您应在定义mySlides之后调用autoSlideshow()。然后,当它出现界限时重新初始化下一个值。调用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); 
+2

我喜欢将这两行合并为'next =(index + 1)%mySlides.length;'这会自动换行。 – Barmar

+0

是的,这是一个更好的方法来做到这一点 –

0

由于您获得了一个超出界限的索引,您会收到错误消息。由于您的数组包含3个元素并且索引从0开始,因此array[3]将超出范围。

除此之外,$('#slideshow .slide')已经给你一个元素的数组,所以不需要为它定义一个额外的数组。此外,请勿在函数中使用setInterval,因为这会最终导致脚本崩溃,因为它会一遍又一遍地被调用,而不会清除它。在您的幻灯片功能中,请勿拨打each,因为这样可以一次完成每张幻灯片的更新。你想要做的是当你的函数被调用时,隐藏所有幻灯片并只显示当前索引。

当索引到达数组末尾时,将其重置为0重新开始。

.hide类似乎是多余的,只需在您的​​中添加一个display: none即可。

像这样的东西会做:

var mySlides = $('#slideshow .slide'); 
 
// whats the start index 
 
var slideIndex = $('#slideshow .show').index(); 
 
// how many slides 
 
var noOfSlides = mySlides.length; 
 

 
function autoSlideshow() { 
 
    // remove the 'show' class of all slides 
 
    mySlides.removeClass('show'); 
 

 
    // add 'show' class to only the slide with the slideIndex index 
 
    mySlides.eq(slideIndex).addClass('show'); 
 

 
    // update index 
 
    slideIndex++; 
 

 
    // restart at 0 
 
    if (slideIndex >= noOfSlides) 
 
    slideIndex = 0; 
 

 
}; 
 

 
autoSlideshow(); 
 
setInterval(autoSlideshow, 3000);
.slide { 
 
    display: none; 
 
} 
 
.show { 
 
    display: block; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> 
 
<section id="slideshow"> 
 
    <div class="auto-slideshow"> 
 
    <img src="http://placehold.it/350x150/333" alt="" class="slide show"> 
 
    <img src="http://placehold.it/350x150/555" alt="" class="slide"> 
 
    <img src="http://placehold.it/350x150/111" alt="" class="slide"> 
 
    </div> 
 
</section>