JavaScript幻灯片不流畅

时间:2016-12-31 05:47:30

标签: javascript jquery html css ecmascript-6

我一直在使用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>

2 个答案:

答案 0 :(得分:2)

jQuery代码中存在多个问题。这是我发现的:

  1. 它正在运行JavaScript运行的竞争条件 之前HTML已经有时间加载。没有最初的div 标签已经加载到文档对象中。容器div 长度为0.具有0ms负载的单个setTimeout将解锁该&amp;在JS运行之前允许加载HTML。
  2. 第3张图像(4.jpg)显示在第1张,而不是第1张图像(6.jpg)。 z-index正在代码中更改,但未应用于图像。
  3. “当前”的不透明度被动画为0&amp;然后立即回升到1.我认为你希望将“next”的不透明度改为1,而不是将“current”从1改为0然后再改回1.
  4. 初始化过渡开始平滑,但是重复动画往往更快地循环播放。在出现“下一个”图像之前淡出到白页。用户可能会发现动画以6秒的延迟开始动摇。然后每张图像加速1/2秒。后一个动画太快了。
  5. 动画是弹出而不是溶解。它也没有使用交叉溶解,但我建议使用一个。我已添加它以向您展示它是如何工作的。
  6. 代码似乎没有被清除,这就是为什么你遇到console.log&amp; amp;的编码问题。被迫使用$ container来纠正它。在将容器变量作为带有(容器)的参数传入之后,不能使用“let container = ...”重新声明容器变量。当我通过传入“selector”参数名称来纠正它,然后我可以删除容器变量上的$。这有助于区分哪些代码与jQuery和amp;不是。
  7. 严重依赖使用setTimeout方法,但正如您可能已经知道的那样...那些只运行1x&amp;然后停下来要使它们连续循环,启动setTimeout已更改为setInterval。
  8. 试试这个edited JS Fiddle,修复这些问题。 顺便说一句,这是jQuery .animate方法。

    CSS更改:

    1. 添加了“不透明度:0;”所有幻灯片。
    2. 添加了“不透明度:1;”到第一张幻灯片。
    3. <强> 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>
      

      edited JS Fiddle玩得开心,以进一步自定义它!

答案 1 :(得分:0)

主要问题在于

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()来更改图像。在animate的完成回调中更改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>

相关问题