I am trying to make an automatic slideshow but this message keeps popping up and I don't understand why.
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>
The 'show' and 'hide' classes set the display to 'block' and 'none' respectively.
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);
};
Any advice or correction is much appreciated.
答案 0 :(得分:1)
首先,您应该在定义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);
答案 1 :(得分:0)
使用您提供的HTML,您可以假设slide变量中包含3个元素。现在,当迭代mySlides时,您将索引分配给变量并使用该值+ 1来访问slides数组的元素。如果您目前在mySlides数组的第3项上会发生什么?索引将是2,next将设置为3.由于幻灯片只有3个值,因此只能到达幻灯片[2],代码正在尝试访问当前未定义的幻灯片索引。
答案 2 :(得分:0)
非常接近,只是几件事。
您正在迭代所有幻灯片,更新所有幻灯片
function autoSlideshow() {
mySlides.each(function () { //code snipped }
}
这是循环遍历所有幻灯片,每次迭代都会将下一张幻灯片设置为可见,因此当循环结束时,您就会回到开始的位置。
每次调用该功能时都会添加一个新的计时器
function autoSlideshow() {
//code snipped
setInterval(autoSlideshow, 3000);
};
每次调用此函数时,都会添加另一个再次调用它的计时器。您只需使用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/
希望有所帮助!
答案 3 :(得分:0)
您收到错误是因为您获得了一个越界索引。由于您的数组包含3个元素且索引从0开始,array[3]
将超出范围。
除此之外,$('#slideshow .slide')
已经为您提供了一系列元素,因此无需为其定义额外的数组。此外,不要在函数内部使用setInterval
,因为这会导致脚本崩溃,因为它会一次又一次地被调用而不会清除它。在幻灯片放映功能中,请不要调用each
,因为这样可以一次性对每张幻灯片进行更新。您要做的是调用函数时,隐藏所有幻灯片并仅显示当前索引。
当索引到达数组的末尾时,将其重置为0以重新开始。
.hide
课程似乎多余,只需在display: none
添加.slide
。
这样的事情会:
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>