簡體   English   中英

JavaScript幻燈片播放不流暢

[英]JavaScript slideshow not smooth

我一直在使用jQuery 3.1.1制作自己的JavaScript幻燈片。 可以,但是由於某種原因,過渡動畫不流暢。 當只有兩張照片時,它可以正常工作,但是一旦我添加了第三張,它就不能很好地工作。

我做了這個小提琴,如果有人可以提供一些見識,將不勝感激。

 !function($) { "use strict"; $.slideshow = function(container) { let $container = $(container); let children = $container.find('.slide').length; $container.find('.slide').each(function(index) { let zIndex = 210 - index; let bg = $(this).data('bg'); $(this).css('background-image', 'url(' + bg + ')'); }); let settings = { 'transition': 500, 'delay': 6000, }; let currentSlide = 0; $.fn.showNext = function() { let nextSlide = ((currentSlide + 1) < children) ? (currentSlide + 1) : 0; let $current = $container.find('.slide:nth-child(' + (currentSlide + 1) + ')'); let $next = $container.find('.slide:nth-child(' + (nextSlide + 1) + ')'); $current.animate({ 'opacity': 0 }, settings.transition); setTimeout(function() { $current.css('z-index', 200); $current.css('opacity', 1); $next.css('z-index', 210); }, settings.transition + 100); console.log(currentSlide, nextSlide); currentSlide = ((currentSlide + 1) < children) ? (currentSlide + 1) : 0; setTimeout(function() { $container.showNext(); }, settings.delay); }; setTimeout(function() { $container.showNext(); }, settings.delay); }; }(jQuery); $.slideshow('.slideshow'); 
  .slideshow-wrapper { height: 100vh; overflow: hidden; position: relative; width: 100%; } .slideshow { height: 100%; position: relative; width: 100%; } .slide { background-position: center; background-size: cover; height: 100%; left: 0; overflow: hidden; position: absolute; top: 0; width: 100%; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> <div class="slideshow-wrapper"> <div class="slideshow"> <div class="slide" data-bg="https://s3.amazonaws.com/StartupStockPhotos/uploads/20160503/6.jpg"></div> <div class="slide" data-bg="https://s3.amazonaws.com/StartupStockPhotos/uploads/20160503/5.jpg"></div> <div class="slide" data-bg="https://s3.amazonaws.com/StartupStockPhotos/uploads/20160503/4.jpg"></div> </div> </div> 

jQuery代碼中存在多個問題。 這是我發現的:

  1. 它正在進入競爭狀態,在這種情況下,JavaScript的運行時間早於HTML的加載時間。 尚未將任何初始div標記加載到文檔對象中。 容器div的長度為0。加載0ms的單個setTimeout將取消阻止並允許HTML加載,然后再運行JS。
  2. 正在顯示第三張圖片(4.jpg),而不是第一張圖片(6.jpg)。 Z-index已在代碼中更改,但未應用回圖像。
  3. 將“當前”的不透明度設置為0動畫,然后立即提高到1。我認為您正在嘗試將“下一個”的不透明度從1改為0,而不是從“當前”的不透明度再更改為1。
  4. 初始化過渡開始時很平滑,但是隨后的重復動畫趨向於更快地循環並逐漸淡出,直到出現“下一個”圖像。 用戶可能會發現震撼動畫的開始時間為6秒,然后每個圖像的速度加快了1/2秒。 后一個動畫太快了。
  5. 動畫彈出而不是溶解。 它也沒有使用交叉溶解,但是我建議使用交叉溶解。 我添加了它以向您展示它是如何工作的。
  6. 該代碼似乎沒有清除,這就是為什么您在console.log中遇到編碼問題並被迫使用$ container對其進行更正的原因。 將容器變量作為參數傳遞給(container)后,不能使用“ let container = ...”重新聲明容器變量。 當我通過傳遞“選擇器”參數名稱來更正該錯誤時,可以刪除容器變量上的$。 這有助於區分哪些代碼與jQuery相關,哪些與否無關。
  7. 很大程度上依賴於使用setTimeout方法,但是您可能已經知道...它們只運行1x然后停止。 為了使它們連續循環,起始setTimeout已更改為setInterval。

試試這個經過編輯的JS Fiddle ,它可以解決那些問題。 順便說一句,這是jQuery .animate方法。

CSS更改:

  1. 添加了“不透明度:0;” 所有幻燈片。
  2. 添加了“不透明度:1;” 到第一張幻燈片。

CSS:

.slideshow-wrapper {
  height: 100vh;
  overflow: hidden;
  position: relative;
  width: 100%;
}

.slideshow {
  height: 100%;
  position: relative;
  width: 100%;
}

.slide {
  background-position: center;
  background-size: cover;
  height: 100%;
  left: 0;
  opacity: 0; /* <-- New --- */
  overflow: hidden;
  position: absolute;
  top: 0;
  width: 100%;
}

.slide:first-child { /* <-- New --- */
  opacity: 1;
}

JavaScript進行了大量修改

!function($) {
   "use strict";

   $.slideshow = function(selector) {
        let container = $(selector);
        let children = container.find('.slide').length;

        container.find('.slide').each(function(index) {
          let zIndex = 210 - index;
          $(this).css('z-index', zIndex); // <-- This was missing, as it was loading the last image as the 1st image.
          let bg = $(this).data('bg');
          $(this).css('background-image', 'url(' + bg + ')');
        });

        let settings = {
          'delay': 2000
        };

        let currentSlide = 0;

        $.fn.showNext = function() {
          let nextSlide = ((currentSlide + 1) < children) ? (currentSlide + 1) : 0;
          let current = container.find('.slide:nth-child(' + (currentSlide + 1) + ')');
          let next = container.find('.slide:nth-child(' + (nextSlide + 1) + ')');

          next.animate({
            'opacity': 1,
            'z-index': 210
          }, settings.transition);

          // Creates the Cross-Dissolve, as 1 image "next" is fadding up from opacity 0 to 1, while current is fadding down from 1 to 0.
          current.animate({
             'opacity': 0,
             'z-index': 200
          }, settings.transition);
       };

       // Starts the animation loop.
       setInterval(function() {
          container.showNext();
          currentSlide = ((currentSlide + 1) < children) ? (currentSlide + 1) : 0;
       }, settings.delay);
   };
}(jQuery);

setTimeout(function() {
   $.slideshow('.slideshow');
}, 0); // Fixes the race condition, by allowing the HTML to load before the JS runs.

HTML-不變,但使用jsfiddle時刪除腳本標簽

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>   
<div class="slideshow-wrapper">
  <div class="slideshow">
    <div class="slide" data-bg="https://s3.amazonaws.com/StartupStockPhotos/uploads/20160503/6.jpg"></div>
    <div class="slide" data-bg="https://s3.amazonaws.com/StartupStockPhotos/uploads/20160503/5.jpg"></div>
    <div class="slide" data-bg="https://s3.amazonaws.com/StartupStockPhotos/uploads/20160503/4.jpg"></div>
  </div>
</div>

玩得開心,與經過編輯的JS Fiddle一起進一步定制它!

主要問題在這里

setTimeout(function() {
        $current.css('z-index', 200);
        $current.css('opacity', 1); // this should be $next.css('opacity', 1);
        $next.css('z-index', 210);
      }

您還應該嘗試擺脫3 setTimeout(),它們看起來很多余。 您可以使用setInteval()更改圖像。 在動畫的完成回調中更改css屬性,然后可以刪除另一個setTimeout()。

檢查一下:

 !function($) { "use strict"; $.slideshow = function(container) { let $container = $(container); let children = $container.find('.slide').length; $container.find('.slide').each(function(index) { let zIndex = 210 - index; let bg = $(this).data('bg'); $(this).css('background-image', 'url(' + bg + ')'); }); let settings = { 'transition': 500, 'delay': 6000, }; let currentSlide = 0; $.fn.showNext = function() { let nextSlide = ((currentSlide + 1) < children) ? (currentSlide + 1) : 0; let $current = $container.find('.slide:nth-child(' + (currentSlide + 1) + ')'); let $next = $container.find('.slide:nth-child(' + (nextSlide + 1) + ')'); $current.animate({ 'opacity': 0 }, settings.transition,function(){ $current.css('z-index', 200); $next.css('opacity', 1); $next.css('z-index', 210); }); currentSlide = ((currentSlide + 1) < children) ? (currentSlide + 1) : 0; }; setInterval(function() { $container.showNext(); }, settings.delay); }; }(jQuery); $.slideshow('.slideshow'); 
 .slideshow-wrapper { height: 100vh; overflow: hidden; position: relative; width: 100%; } .slideshow { height: 100%; position: relative; width: 100%; } .slide { background-position: center; background-size: cover; height: 100%; left: 0; overflow: hidden; position: absolute; top: 0; width: 100%; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> <div class="slideshow-wrapper"> <div class="slideshow"> <div class="slide" data-bg="https://s3.amazonaws.com/StartupStockPhotos/uploads/20160503/6.jpg"></div> <div class="slide" data-bg="https://s3.amazonaws.com/StartupStockPhotos/uploads/20160503/5.jpg"></div> <div class="slide" data-bg="https://s3.amazonaws.com/StartupStockPhotos/uploads/20160503/4.jpg"></div> </div> </div> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM