JavaScript 幻灯片放映不流畅

标签 javascript jquery html css ecmascript-6

我一直在使用 jQuery 3.1.1 制作我自己的 JavaScript 幻灯片。它工作正常,但由于某种原因,过渡动画不流畅。当只有两张照片时,它工作正常,但一旦我添加了第三张照片,它就完全不能正常工作了。

我做了这个 fiddle ,如果有人能提供一些见解,我将不胜感激。

!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 标记已加载到文档对象中。容器分区 长度为 0。加载 0 毫秒的单个 setTimeout 将取消阻止并允许在 JS 运行之前加载 HTML。
  2. 第 3 张图片 (4.jpg) 第一张显示,而不是第 1 张图片 (6.jpg)。代码中更改了 z-index,但未将其应用回图像。
  3. “current”的不透明度正在动画化为 0,然后立即回升到 1。我认为您要将“next”的不透明度更改为 1,而不是将“current”的不透明度从 1 更改为 0,并且然后回到 1。
  4. 初始化过渡开始时很流畅,但随后重复动画往往会循环得更快,并在“下一个”图像出现之前淡出到白页。用户可能会发现动画以 6 秒的延迟开始,然后每张图像加速到 1/2 秒。后一个动画太快了。
  5. 动画是弹出而不是消失。它也没有使用交叉溶解,但我建议使用一个。我添加它是为了向您展示它是如何工作的。
  6. 代码似乎没有被清理,这就是为什么您遇到 console.log 的编码问题并被迫使用 $container 来更正它的原因。 container 变量在用(container) 作为参数传入后,不能用“let container = ...”重新声明。当我通过传入“选择器”参数名称更正它时,我可以删除容器变量上的 $。这有助于区分哪些代码与 jQuery 绑定(bind),哪些不绑定(bind)。
  7. 严重依赖于使用 setTimeout 方法,但正如您可能已经知道的那样......那些只运行 1x 然后停止。为了让它们连续循环,开始的 setTimeout 已更改为 setInterval。

试试这个 edited 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>

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

关于JavaScript 幻灯片放映不流畅,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41405840/

相关文章:

javascript - 动画侧边栏在调整大小时中断

javascript - 使用 jquery sort() 函数对元素进行排序在 webkit 上失败

jquery - 拉伸(stretch)屏幕时响应式移动导航问题

javascript - 页面内样式标签内的 CSS 加载,但不从外部样式表加载

javascript - 如何在没有单击或来自 php 的 onload 事件的情况下执行 javascript?

javascript - 表格行中的 CSS 样式问题

javascript - 在 React 中调用 onClick 函数

javascript - 如何在正则表达式中使用变量?

javascript - 使用 Javascript/JQuery 替换 `<a>` 的正确方法是什么?

html - 您的HTML插件无法正常工作