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

Images won't co-ordinate in sync between two blocks when using a keyframe image rotator

本文关键字:图像 两个 之间 协调 同步 旋转 关键帧      更新时间:2023-09-26

我有一个几乎很好的双层图像滑块工作代码。我初步创建了 2 个独立但相同的图像滑块,其中图像在循环图像的背景顶部滑入和滑出视图,但背景图像不会在两个图像块上同步协调。当然可以使用一些帮助。

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

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 演示,要查看我现在尝试以现有形式将其应用于什么,您可以在我的网站上查看。

TL;DR: (简答题)

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

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

因此,您的循环有效地从 0 到 5 而不是从 0 到 2 工作,这会导致图像不同步。


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

下面是您的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数(或者只是获取总数并像我所做的那样除以 2)并隐藏/显示对应于每个幻灯片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);
};

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

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>