web-dev-qa-db-ja.com

滑らかなスライダー-css遷移の無限ループのバグ

スリックスライダーを使用してスライダーを設定しました。 [次へ]ボタンと[前へ]ボタンを使用すると、項目が表示されて素敵なトランジションが表示されます。私が抱えている問題は、サイクルを再開すると、最初のアイテムが遷移する代わりに「スナップ」して表示されることです。さらに、CSSの「奇数」および「偶数」クラスが変更されるため、内部インデックスが失われるようです。以下のスニペットを参照してください。

$(document).ready(function() {
    $('.items').slick({
        slidesToShow: 2,
        speed: 500
    });
});
* {
  margin: 0;
  padding: 0;
}

ul {
  list-style: none;
  height: 150px;
}

.slick-list, .slick-track {
  height: 100%;
}

ul li {
  width: 350px;
  height: 100%;
}

ul li .content {
  width: 100%;
  height: 100%;
  transition: transform 0.5s linear;
  text-align: center;
}

ul li .content span {
  color: #fff;
  font-size: 50px;
  font-family: Arial;
  position: relative;
  top: 50%;
  transform: translateY(-50%);
  display: block;
}

ul li:nth-child(odd) .content {
  background-color: red;
}

ul li:nth-child(even) .content {
  background-color: green;
}

ul li:not(.slick-current) .content {
  transform: scale(0.9);
}
<link href="https://cdn.jsdelivr.net/jquery.slick/1.6.0/slick.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/jquery.slick/1.6.0/slick.min.js"></script>
<ul class="items">
  <li class="item">
    <div class="content">
      <span>1</span>
    </div>
  </li>

  <li class="item">
    <div class="content">
      <span>2</span>
    </div>
  </li>

  <li class="item">
    <div class="content">
      <span>3</span>
    </div>
  </li>

  <li class="item">
    <div class="content">
      <span>4</span>
    </div>
  </li>

  <li class="item">
    <div class="content">
      <span>5</span>
    </div>
  </li>
</ul>

なぜこれを行うのか知っていると思います。無限ループ機能が機能するためには「クローン」アイテムを作成する必要があるからです。私はいくつかの異なるスライダープラグインを試しましたが、それらはすべて同様の問題を抱えているようです。

誰も私がこれを修正する方法を知っていますか?ここのjsfiddle: https://jsfiddle.net/7kdmwkd9/1/

14
GSTAR

解決策1-Flickityを使用する

別のカルーセルコントロールを試したい場合は、 Flickity をご覧ください。 wrapAroundオプションを使用したテストによると、完全なサイクルが完了したときに最初のアイテムを「スナップ」して元の位置に戻しません。移行はスムーズに進みます。 this jsfiddle で作業中に確認できます。

偶数/奇数インデックスに従ってアイテムをフォーマットする際の問題に関しては、奇数のアイテムがある場合にのみ発生します。 1つの解決策は、アイテムのリストを複製することです。の代わりに

Item 1 / Item 2 / Item 3 / Item 4 / Item 5

定義できます

Item 1 / Item 2 / Item 3 / Item 4 / Item 5 / Item 1 / Item 2 / Item 3 / Item 4 / Item 5

これにより、偶数のアイテムで作業することが保証されます。


解決策2-スリックスライダー:遷移遅延を追加

Slick Sliderを使用すると、遷移に遅延を追加することで、サイクルの完了時に滑らかになります。以下のコードスニペットで、私は置き換えました:

ul li .content {
  transition: transform 0.5s linear;
  ...
}

ul li:not(.slick-current) .content {
  transform: scale(0.9);
}

ul li .content {
  transition: transform 0.3s linear;
  transition-delay: 0.5s;
  ...
}

ul li:not(.slick-current) .content {
  transform: scale(0.9);
  transition-delay: 0s;
}
$(document).ready(function() {
  $('.items').slick({
    infinite: true,
    speed: 500,
    slidesToShow: 2,
    variableWidth: false
  });
});
* {
  margin: 0;
  padding: 0;
}

ul {
  list-style: none;
  height: 150px;
}

.slick-list,
.slick-track {
  height: 100%;
}

ul li {
  width: 350px;
  height: 100%;
}

ul li .content {
  width: 100%;
  height: 100%;
  transition: transform 0.3s linear;
  transition-delay: 0.5s;
  text-align: center;
}

ul li .content span {
  color: #fff;
  font-size: 50px;
  font-family: Arial;
  position: relative;
  top: 50%;
  transform: translateY(-50%);
  display: block;
}

ul li:nth-child(odd) .content {
  background-color: red;
}

ul li:nth-child(even) .content {
  background-color: green;
}

ul li:not(.slick-current) .content {
  transform: scale(0.9);
  transition-delay: 0s;
}
<link href="https://cdn.jsdelivr.net/jquery.slick/1.6.0/slick.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/jquery.slick/1.6.0/slick.min.js"></script>
<ul class="items">
  <li class="item">
    <div class="content">
      <span>1</span>
    </div>
  </li>
  <li class="item">
    <div class="content">
      <span>2</span>
    </div>
  </li>
  <li class="item">
    <div class="content">
      <span>3</span>
    </div>
  </li>
  <li class="item">
    <div class="content">
      <span>4</span>
    </div>
  </li>
  <li class="item">
    <div class="content">
      <span>5</span>
    </div>
  </li>
  <li class="item">
    <div class="content">
      <span>1</span>
    </div>
  </li>
  <li class="item">
    <div class="content">
      <span>2</span>
    </div>
  </li>
  <li class="item">
    <div class="content">
      <span>3</span>
    </div>
  </li>
  <li class="item">
    <div class="content">
      <span>4</span>
    </div>
  </li>
  <li class="item">
    <div class="content">
      <span>5</span>
    </div>
  </li>
</ul>
11
ConnorsFan

@GSTAR、最終的にはコードにエラーはありませんが、slickの使用中に理解する必要のあるcssおよびjsフローが少しあります。

Slickはスライドのクローンを作成し、スライドの上下を修正します。以下に説明するように。

Slick実装前のコード

<ul class="items">
    <li class="item"><div class="content"><span>1</span></div></li>
    <li class="item"><div class="content"><span>2</span></div></li>
    <li class="item"><div class="content"><span>3</span></div></li>
    <li class="item"><div class="content"><span>4</span></div></li>
    <li class="item"><div class="content"><span>5</span></div></li>
    <li class="item"><div class="content"><span>6</span></div></li>
</ul>

Slick実装後のコード

<ul class="items">
    <li class="item slick-cloned"><div class="content"><span>4</span></div></li>
    <li class="item slick-cloned"><div class="content"><span>5</span></div></li>
    <li class="item slick-cloned"><div class="content"><span>6</span></div></li>

    <li class="item"><div class="content"><span>1</span></div></li>
    <li class="item"><div class="content"><span>2</span></div></li>
    <li class="item"><div class="content"><span>3</span></div></li>
    <li class="item"><div class="content"><span>4</span></div></li>
    <li class="item"><div class="content"><span>5</span></div></li>
    <li class="item"><div class="content"><span>6</span></div></li>

    <li class="item slick-cloned"><div class="content"><span>1</span></div></li>
    <li class="item slick-cloned"><div class="content"><span>2</span></div></li>
    <li class="item slick-cloned"><div class="content"><span>3</span></div></li>
</ul>

また、これを追加した後、animationコードは正常に機能します。しかし、視覚的には見えません。このanimation時間を増やすと、ブラウザがスナップしないsnapsになります。

JavaScriptコードを置き換えると、何が起こっているのかがわかります。

<script type="text/javascript">
    $(document).ready(function() {
        $('.items').slick({
            centerMode:true,
            slidesToShow: 3,
            speed: 500,
            infinite: true,
            cssEase: 'linear',
            variableWidth: true
        });
    });
</script>

そのため、ループが終了して実行された最初のスライドアニメーションに到達した後、到達する前に終了します。

以下のスニペットを確認してください。

$(document).ready(function() {
    $('.items').slick({
        slidesToShow: 2,
        speed: 500
    });
});
* {
  margin: 0;
  padding: 0;
}

ul {
  list-style: none;
  height: 150px;
}

.slick-list, .slick-track {
  height: 100%;
}

ul li {
  width: 350px;
  height: 100%;
}

ul li .content {
  width: 100%;
  height: 100%;
  transition: transform 0.5s linear;
  transition-delay: 0.5s;
  text-align: center;
}

ul li .content span {
  color: #fff;
  font-size: 50px;
  font-family: Arial;
  position: relative;
  top: 50%;
  transform: translateY(-50%);
  display: block;
}

ul li:nth-child(odd) .content {
  background-color: red;
}

ul li:nth-child(even) .content {
  background-color: green;
}

ul li:not(.slick-current) .content {
  transform: scale(0.9);
}
<link href="https://cdn.jsdelivr.net/jquery.slick/1.6.0/slick.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/jquery.slick/1.6.0/slick.min.js"></script>
<ul class="items">
  <li class="item">
    <div class="content">
      <span>1</span>
    </div>
  </li>

  <li class="item">
    <div class="content">
      <span>2</span>
    </div>
  </li>

  <li class="item">
    <div class="content">
      <span>3</span>
    </div>
  </li>

  <li class="item">
    <div class="content">
      <span>4</span>
    </div>
  </li>

  <li class="item">
    <div class="content">
      <span>5</span>
    </div>
  </li>
  <li class="item">
    <div class="content">
      <span>6</span>
    </div>
  </li>
</ul>

無限ループでは、ユーザーoddおよびeven cssがあるため、ループごとに次のfirstスライド(クローンスライド)は緑色ですが、元のスライド(最初のスライド)は赤色なので、色をフリックします。 %2で多数のスライドを使用する場合、これは起こりません。

enter image description here

それがあなたがよりよく理解するのに役立つことを願っています。

6

これは問題ではなく、機能です-これは、滑らかなスライダー(および他のほとんどの無限ループスライダー)が機能する方法です。基本的に、スライダーがdivを複製するだけの場合、パフォーマンス上の大きな問題が発生するため、アニメーション後の特定の場所(開始/終了)で最初からやり直します。

ここに興味がある場合は、遷移に基づいており、何も複製せず、位置を変更するだけのスライダーの概念実証です。また、orderで同じことを実現する可能性があるかもしれません-試していないが、今考えました。

https://codepen.io/prowseed/pen/QMEQxg -もちろん、完全に使用可能にするためには多くの作業が必要ですが、応答性を高め、あなたの例に最も近いものにしようとしました。特定のクラスを追加/削除するには、インデックスを追跡する必要があります(.current 例えば)。

3
Maciej Kwas

ここで、slick.jsの私のハック警告!!慎重に使用し、プラグインのソースコードを変更します

1)検索機能
Slick.prototype.setSlideClassesからその定義を置き換えます

 Slick.prototype.setSlideClasses = function(index) 

Slick.prototype.setSlideClasses = function(index, oldSlide)

2)コードの後のこの関数の本体

_.$slides
    .eq(index)
    .addClass('slick-current');

追加

if(oldSlide!=undefined){
    if(index==0 && oldSlide!=1){
        var _current = this.$slides.eq(this.$slides.size()-1);
        var __index = allSlides.index(_current);
        var ss = allSlides.eq(__index+1);
        ss.addClass('slick-current');
    }
    if(index==this.$slides.size()-1 && oldSlide!=this.$slides.size()-2){
        var _current = this.$slides.eq(0);
        var __index = allSlides.index(_current);
        var ss = allSlides.eq(__index-1);
        ss.addClass('slick-current');
    }
}

3)関数の検索Slick.prototype.slideHandler本体の置換呼び出し

oldSlide = _.currentSlide;
_.currentSlide = animSlide;
_.setSlideClasses(_.currentSlide);

oldSlide = _.currentSlide;
_.currentSlide = animSlide;
_.setSlideClasses(_.currentSlide,oldSlide);
2
rudenich

@Maciej Kwas

これは機能かもしれませんが、このサイトでは、スライダーを「センターモード」で見ると正常に動作し、最後のスライドから最初のスライドにスライドするときにアニメーションは正常に見えます。 http://kenwheeler.github.io/slick/

0