javascript - 使用关键帧图像旋转器时,图像不会在两个 block 之间同步协调

标签 javascript jquery html css

我有一个双层图像 slider 的几乎可以正常工作的代码。我暂时创建了 2 个独立但相同的图像 slider ,其中图像在自行车图像背景的顶部滑入和滑出 View ,但背景图像不会在两个图像 block 上同步协调。当然可以使用一些帮助。

下面是基于我的代码的片段:

function cycleBackgrounds() {
  var index = 0;

  $imageEls = $('.toggle-image'); // Get the images to be cycled.

  setInterval(function() {
    // Get the next index.  If at end, restart to the beginning.
    index = index + 1 < $imageEls.length ? index + 1 : 0;
    // Show the next image.
    $imageEls.eq(index).addClass('show');
    // Hide the previous image.
    $imageEls.eq(index - 1).removeClass('show');

  }, 10000);
};

// Document Ready.
$(function() {
  cycleBackgrounds();
});
body {
  background-color: #000000
}
table {
  margin: auto;
  border-collapse: separate;
  border-spacing: 100px 0px;
}
.slideshow1 {
  width: 104px;
  z-index: 0;
  height: 219px;
  overflow: hidden;
  position: relative;
}
.slid_1,
.slid_2,
{
  position: absolute;
  width: 104px;
  height: 219px;
}
.slid_1 {
  left: 0;
}
.slid_2 {
  left: 104px;
}
.slide1 {
  width: 104px;
  height: 219px;
  left: 0px;
  position: absolute;
  -webkit-animation-duration: 20s;
  -webkit-animation-iteration-count: infinite;
  -webkit-animation-name: anim_slide1;
  -moz-animation-duration: 20s;
  -moz-animation-iteration-count: infinite;
  -moz-animation-name: anim_slide1;
  -ms-animation-duration: 20s;
  -ms-animation-iteration-count: infinite;
  -ms-animation-name: anim_slide1;
  animation-duration: 20s;
  animation-iteration-count: infinite;
  animation-name: anim_slide1;
  -webkit-animation-delay: 2s;
  -ms-animation-delay: 2s;
  animation-delay: 2s;
}
}
@-webkit-keyframes anim_slide1 {
  0% {
    left: 0px;
  }
  20% {
    left: 0px;
  }
  21% {
    left: 105px;
  }
  29% {
    left: 105px;
  }
  30% {
    left: 0px;
  }
  70% {
    left: 0px;
  }
  71% {
    left: -105px;
  }
  79% {
    left: -105px;
  }
  80% {
    left: 0px;
  }
  100% {
    left: 0px;
  }
}
@-moz-keyframes anim_slide1 {
  0% {
    left: 0px;
  }
  20% {
    left: 0px;
  }
  21% {
    left: 105px;
  }
  29% {
    left: 105px;
  }
  30% {
    left: 0px;
  }
  70% {
    left: 0px;
  }
  71% {
    left: -105px;
  }
  79% {
    left: -105px;
  }
  80% {
    left: 0px;
  }
  100% {
    left: 0px;
  }
}
@-ms-keyframes anim_slide1 {
  0% {
    left: 0px;
  }
  20% {
    left: 0px;
  }
  21% {
    left: 105px;
  }
  29% {
    left: 105px;
  }
  30% {
    left: 0px;
  }
  70% {
    left: 0px;
  }
  71% {
    left: -105px;
  }
  79% {
    left: -105px;
  }
  80% {
    left: 0px;
  }
  100% {
    left: 0px;
  }
}
@keyframes anim_slide1 {
  0% {
    left: 0px;
  }
  20% {
    left: 0px;
  }
  21% {
    left: 105px;
  }
  29% {
    left: 105px;
  }
  30% {
    left: 0px;
  }
  70% {
    left: 0px;
  }
  71% {
    left: -105px;
  }
  79% {
    left: -105px;
  }
  80% {
    left: 0px;
  }
  100% {
    left: 0px;
  }
}
.slideshow {
  width: 104px;
  z-index: 0;
  height: 219px;
  overflow: hidden;
  position: relative;
}
.slid_1,
.slid_2,
{
  position: absolute;
  width: 104px;
  height: 219px;
}
.slid_1 {
  left: 0;
}
.slid_2 {
  left: 104px;
}
.slide {
  width: 104px;
  height: 219px;
  left: 0px;
  position: absolute;
  -webkit-animation-duration: 50s;
  -webkit-animation-iteration-count: infinite;
  -webkit-animation-name: anim_slide;
  -moz-animation-duration: 10s;
  -moz-animation-iteration-count: infinite;
  -moz-animation-name: anim_slide;
  -ms-animation-duration: 10s;
  -ms-animation-iteration-count: infinite;
  -ms-animation-name: anim_slide;
  animation-duration: 10s;
  animation-iteration-count: infinite;
  animation-name: anim_slide;
  -webkit-animation-delay: 10s;
  -ms-animation-delay: 2s;
  animation-delay: 2s;
}
}
@-webkit-keyframes anim_slide {
  0% {
    left: 0px;
  }
  20% {
    left: 0px;
  }
  21% {
    left: -105px;
  }
  29% {
    left: -105px;
  }
  30% {
    left: 0px;
  }
  70% {
    left: 0px;
  }
  71% {
    left: 105px;
  }
  79% {
    left: 105px;
  }
  80% {
    left: 0px;
  }
  100% {
    left: 0px;
  }
}
@-moz-keyframes anim_slide {
  0% {
    left: 0px;
  }
  20% {
    left: 0px;
  }
  21% {
    left: -105px;
  }
  29% {
    left: -105px;
  }
  30% {
    left: 0px;
  }
  70% {
    left: 0px;
  }
  71% {
    left: 105px;
  }
  79% {
    left: 105px;
  }
  80% {
    left: 0px;
  }
  100% {
    left: 0px;
  }
}
@-ms-keyframes anim_slide {
  0% {
    left: 0px;
  }
  20% {
    left: 0px;
  }
  21% {
    left: -105px;
  }
  29% {
    left: -105px;
  }
  30% {
    left: 0px;
  }
  70% {
    left: 0px;
  }
  71% {
    left: 105px;
  }
  79% {
    left: 105px;
  }
  80% {
    left: 0px;
  }
  100% {
    left: 0px;
  }
}
@keyframes anim_slide {
  0% {
    left:0px;
  }
  20% {
    left: 0px;
  }
  21% {
    left: -105px;
  }
  29% {
    left: -105px;
  }
  30% {
    left: 0px;
  }
  70% {
    left: 0px;
  }
  71% {
    left: 105px;
  }
  79% {
    left: 105px;
  }
  80% {
    left: 0px;
  }
  100% {
    left: 0px;
  }
}
/* Styles for the alternating / transition effect. */

.toggle-image {
  position:absolute;
  width:100%;
  top:0;
  left:0;
  height:219px;
  transition:opacity 1s ease-in-out;
}
/* Styles for the specific images. */

.first-image {
  background-image:url('http://s16879.storage.proboards.com/6436879/i/OfhfhHNr42EQE_jVr3sM.gif');
  background-size:104px 219px;
  z-index:-1;
  opacity:0;
}
.second-image {
  background-image:url('http://s16879.storage.proboards.com/6436879/i/Q1bqSCICZHlq5KP4jLCI.gif');
  background-size:104px 219px;
  z-index:-1;
  opacity:0;
}
.third-image {
  background-image:url('http://s16879.storage.proboards.com/6436879/i/v_8VBpL9eMq_hS4JFyp_.gif');
  background-size:104px 219px;
  z-index:-1;
  opacity:0;
}
.first-image.show {
  opacity:1;
}
.second-image.show {
  opacity:1;
}
.third-image.show {
  opacity:1;
}
/* Styles for the alternating / transition effect. */

.toggles-image {
  position:absolute;
  width:100%;
  top:0;
  left:0;
  height:219px;
  transition:opacity 1s ease-in-out;
}
<table>
  <tr>
    <td>
      <script src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
      <!--[if gte IE 9]><!-->
      <div class="slideshow1">
        <!--<![endif]-->
        <!--[if gte IE 9]><!-->
        <div class="slide1">
          <!--<![endif]-->
          <img src="http://s16879.storage.proboards.com/6436879/i/ihfBlEhkcXWqZh3B8tOm.gif" width="104px" height="219px" />
        </div>
        <div class="background-image toggle-image first-image show"></div>
        <div class="background-image toggle-image second-image"></div>
        <div class="background-image toggle-image third-image"></div>
    </td>
    <td></td>
    <td>

      <script src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
      <!--[if gte IE 9]><!-->
      <div class="slideshow1">
        <!--<![endif]-->
        <!--[if gte IE 9]><!-->
        <div class="slide1">
          <!--<![endif]-->
          <img src="http://s16879.storage.proboards.com/6436879/i/ihfBlEhkcXWqZh3B8tOm.gif" width="104px" height="219px" />
        </div>
        <div class="background-image toggle-image first-image show"></div>
        <div class="background-image toggle-image second-image"></div>
        <div class="background-image toggle-image third-image"></div>
    </td>
  </tr>
</table>

这是一个CodePen Demo并查看我现在尝试将其应用于现有形式的内容,您可以查看 on my site .

最佳答案

TL;DR:(简答)

是因为你的JS是怎么写的。当您使用以下语句获取图像元素时,您基本上是在页面中获取所有带有 class = 'toggle-image' 的元素,并且有六个这样的元素(第一个幻灯片中的三个 div 和第二个中的三个)。

$imageEls = $('.toggle-image');

因此,您的循环实际上是从 0 到 5 而不是从 0 到 2,这导致图像不同步。


长答案:为什么两个 block 中的图像不同步?

下面是您的 HTML 结构,为了便于解释,我在其旁边添加了每个图像元素的索引号(作为注释):

<div class="slideshow1">
  <div class="slide1">
    <img src="http://s16879.storage.proboards.com/6436879/i/ihfBlEhkcXWqZh3B8tOm.gif" width="104px" height="219px" />
  </div>
  <div class="background-image toggle-image first-image show"></div> <!-- index = 0 -->
  <div class="background-image toggle-image second-image"></div> <!-- index = 1 -->
  <div class="background-image toggle-image third-image"></div> <!-- index = 2 -->
</div>
<!-- stripped out code irrelevant to answer -->
<div class="slideshow1">
  <div class="slide1">
    <img src="http://s16879.storage.proboards.com/6436879/i/ihfBlEhkcXWqZh3B8tOm.gif" width="104px" height="219px" /> </div>
  <div class="background-image toggle-image first-image show"></div> <!-- index = 3 -->
  <div class="background-image toggle-image second-image"></div> <!-- index = 4 -->
  <div class="background-image toggle-image third-image"></div> <!-- index = 5 -->
</div>

现在让我们看看循环(通过 setInterval)是如何工作的。但在我们这样做之前,请注意索引为 0 和 3 的图像元素(即幻灯片 div 下的第一张图像)在页面加载时可见,因为它们具有 class='show ' 在 HTML 中手动添加。

Interval No  | Index 0   | Index 1   | Index 2   | Index 3    | Index 4   | Index 5
-----------------------------------------------------------------------------------------
(Page load)  | Visible   | Invisible | Invisible | Visible   | Invisible | Invisible 
1st Interval | Invisible | Visible   | Invisible | Visible   | Invisible | Invisible
2nd Interval | Invisible | Invisible | Visible   | Visible   | Invisible | Invisible
3rd Interval | Invisible | Invisible | Invisible | Visible   | Invisible | Invisible
4th Interval | Invisible | Invisible | Invisible | Invisible | Visible   | Invisible
5th Interval | Invisible | Invisible | Invisible | Invisible | Invisible | Visible

正如您从上表中看到的,在可见图像方面存在明显的脱节。


解决方案是什么?

您实际需要做的是获取每个幻灯片 div 下的 imageEls 的数量(或者像我一样获取总数并除以二)并隐藏/在每个幻灯片 div 下显示与索引号对应的元素,而不是使用全局文档级索引。

function cycleBackgrounds() {
  var index = 0;
  $slideShows = $('.slideshow1');
  $imageEls = $('.toggle-image'); // Get the images to be cycled.

  setInterval(function() {

    // Get the next index.  If at end, restart to the beginning.
    // Since we are dividing it by 2, the loop would only go from index = 0 to 2.
    index = index + 1 < ($imageEls.length / 2) ? index + 1 : 0;

    // Show the next image corresponding to the index under each slideshow
    $slideShows.each(function() {
      $(this).children('.toggle-image').eq(index).addClass('show');
      // Hide the previous image.
      $(this).children('.toggle-image').eq(index - 1).removeClass('show');
    });
  }, 10000);
};

Demo:(我删除了很多重复的、不必要的代码和浏览器前缀版本)

function cycleBackgrounds() {
  var index = 0;
  $slideShows = $('.slideshow1');
  $imageEls = $('.toggle-image');

  setInterval(function() {
    index = index + 1 < ($imageEls.length / 2) ? index + 1 : 0;
    $slideShows.each(function() {
      $(this).children('.toggle-image').eq(index).addClass('show');
      $(this).children('.toggle-image').eq(index - 1).removeClass('show');
    });
  }, 10000);
};

$(function() {
  cycleBackgrounds();
});
body {
  background-color: #000000
}
table {
  margin: auto;
  border-collapse: separate;
  border-spacing: 100px 0px;
}
.slideshow1 {
  width: 104px;
  z-index: 0;
  height: 219px;
  overflow: hidden;
  position: relative;
}
.slid_1,
.slid_2,
{
  position: absolute;
  width: 104px;
  height: 219px;
}
.slid_1 {
  left: 0;
}
.slid_2 {
  left: 104px;
}
.slide1 {
  width: 104px;
  height: 219px;
  left: 0px;
  position: absolute;
  animation-duration: 20s;
  animation-iteration-count: infinite;
  animation-name: anim_slide1;
  animation-delay: 2s;
}
@keyframes anim_slide1 {
  0% {
    left: 0px;
  }
  20% {
    left: 0px;
  }
  21% {
    left: 105px;
  }
  29% {
    left: 105px;
  }
  30% {
    left: 0px;
  }
  70% {
    left: 0px;
  }
  71% {
    left: -105px;
  }
  79% {
    left: -105px;
  }
  80% {
    left: 0px;
  }
  100% {
    left: 0px;
  }
}

/* Styles for the alternating / transition effect. */

.toggle-image {
  position:absolute;
  width:100%;
  top:0;
  left:0;
  height:219px;
  transition:opacity 1s ease-in-out;
}

/* Styles for the specific images. */

.first-image {
  background-image:url('http://s16879.storage.proboards.com/6436879/i/OfhfhHNr42EQE_jVr3sM.gif');
  background-size:104px 219px;
  z-index:-1;
  opacity:0;
}
.second-image {
  background-image:url('http://s16879.storage.proboards.com/6436879/i/Q1bqSCICZHlq5KP4jLCI.gif');
  background-size:104px 219px;
  z-index:-1;
  opacity:0;
}
.third-image {
  background-image:url('http://s16879.storage.proboards.com/6436879/i/v_8VBpL9eMq_hS4JFyp_.gif');
  background-size:104px 219px;
  z-index:-1;
  opacity:0;
}
.first-image.show {
  opacity:1;
}
.second-image.show {
  opacity:1;
}
.third-image.show {
  opacity:1;
}
<script src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
<table>
  <tr>
    <td>
      <div class="slideshow1">
        <div class="slide1">
          <img src="http://s16879.storage.proboards.com/6436879/i/ihfBlEhkcXWqZh3B8tOm.gif" width="104px" height="219px" />
        </div>
        <div class="background-image toggle-image first-image show"></div>
        <div class="background-image toggle-image second-image"></div>
        <div class="background-image toggle-image third-image"></div>
      </div>
    </td>
    <td></td>
    <td>
      <div class="slideshow1">
        <div class="slide1">
          <img src="http://s16879.storage.proboards.com/6436879/i/ihfBlEhkcXWqZh3B8tOm.gif" width="104px" height="219px" />
        </div>
        <div class="background-image toggle-image first-image show"></div>
        <div class="background-image toggle-image second-image"></div>
        <div class="background-image toggle-image third-image"></div>
      </div>
    </td>
  </tr>
</table>

关于javascript - 使用关键帧图像旋转器时,图像不会在两个 block 之间同步协调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35681732/

相关文章:

javascript - 如何根据下拉值切换多个元素的可见性

javascript - JavaScript 和 jQuery 中的 this 和 function

javascript - 重新加载外部 javascript 文件的最佳和快速实践?

javascript - 使用 jQuery .hide/.show 仅显示和隐藏一个 <div>

html - 2 "style"内联 css img 标签?

javascript - 将 jQuery 生成的值传递给 PHP Mail

javascript - 无法使用 jQuery 获取 anchor 标记的 href 值

javascript - 使用 angularJs 单击时更改图标

javascript - 当用户输入输入值时,如何使用 jquery 或 javascript 将 int 转换为 double

html - Windows批处理文件在html文件中查找变量字符串