2016-06-13 75 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>