web-dev-qa-db-fra.com

slick slider - bug de boucle infinie de transition css

J'ai un curseur mis en place en utilisant slider slider. Lorsque vous utilisez les boutons suivant et précédent, l'élément entre en mode d'affichage avec une transition de Nice. Le problème que je rencontre est que, lorsque le cycle redémarre, le premier élément "s'affiche" au lieu de faire la transition. De plus, il semble perdre l'indexation interne, car les classes css "impaires" et "paires" sont modifiées. Voir l'extrait ci-dessous:

$(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>

Je pense que je sais pourquoi cela se produit, c'est parce qu'il doit créer des éléments "clonés" pour que la fonctionnalité de boucle infinie fonctionne. J'ai essayé quelques plugins de curseur différents et ils semblent tous avoir des problèmes similaires.

Est-ce que quelqu'un sait comment je peux résoudre ce problème? jsfiddle ici: https://jsfiddle.net/7/7kdmwkd9/1/

13
GSTAR

Solution 1 - Utilisez le scintillement

Si vous voulez essayer un autre contrôle de carrousel, vous pouvez regarder Flickity . Selon mes tests avec l'option wrapAround, il ne "ramène" pas le premier élément en position lorsque le cycle complet est terminé; la transition se fait sans heurts. Vous pouvez le voir au travail dans ce jsfiddle .

En ce qui concerne le problème de formatage des éléments en fonction de leur index pair/impair, il ne se produit que lorsque vous avez un nombre impair d'éléments. Une solution serait de dupliquer la liste des éléments. Au lieu de 

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

vous pourriez définir

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

Cela garantirait que vous travailliez avec un nombre pair d'éléments.


Solution 2 - Slick Slider: ajout du délai de transition

Avec Slick Slider, l’ajout d’un délai à la transition contribue à l’assouplir à la fin du cycle. Dans l'extrait de code ci-dessous, j'ai remplacé:

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

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

avec

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>

10
ConnorsFan

@GSTAR, Finalement, il n'y a pas d'erreur dans votre code mais il y a un flux de bits css et js que vous devez comprendre lors de l'utilisation de slick.

Slick clone vos diapositives et les modifie en haut et en bas de votre diapositive. comme décrit ci-dessous.

Votre code avant l'implémentation 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>

Votre code après l'implémentation 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>

De plus, après avoir ajouté ceci, votre code animation fonctionne correctement. mais cela ne peut pas être visible visuellement. Si vous augmentez ce temps animation, il ne sera pas claqué dans votre navigateur.

Si vous remplacez le code javascript, vous saurez ce qui se passe.

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

Ainsi, une fois la boucle terminée, la première animation de diapositive exécutée doit être atteinte.

S'il vous plaît vérifier ci-dessous mon extrait.

$(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>

Dans la boucle infinie, vous avez les utilisateurs odd et even css. Ainsi, conformément à la boucle, votre prochaine diapositive first (diapositive clonée) a une couleur verte, mais votre diapositive d'origine (première diapositive) est de couleur rouge. Si vous utilisez le nombre de diapositives dans %2, cela ne se produira pas.

 enter image description here

J'espère que cela vous aidera à mieux comprendre.

5
Shyam Shingadiya

Ce n'est pas un problème, c'est une fonctionnalité - c'est juste comment fonctionne slider slider (et la plupart des autres curseurs à boucle infinie) fonctionne. Fondamentalement, si slider ne clonait que des divs, il en résulterait un énorme problème de performances. Ainsi, à certains endroits (début/fin) après animation, il restituerait le tout pour recommencer.

Si vous êtes intéressé, voici une preuve de concept du curseur basée sur la transition et ne clonant rien, mais modifiant simplement les positions. Il est également possible d’atteindre le même résultat avec order - je n’ai pas essayé, mais y réfléchissons maintenant.

https://codepen.io/prowseed/pen/QMEQxg - Bien sûr, cela demande beaucoup de travail pour le rendre pleinement utilisable, mais j’ai essayé de le rendre réactif et le plus semblable à votre exemple. Il suffit de suivre l'index pour ajouter/supprimer certaines classes (.current par exemple).

3
Maciej Kwas

Voici mon hack pour slick.js Attention !! utilise ses soigneusement, cause son alter code source de plugin

1) fonction de recherche
Slick.prototype.setSlideClasses et remplacer sa définition de 

 Slick.prototype.setSlideClasses = function(index) 

à 

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

2) dans le corps de cette fonction après le code

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

ajouter

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) trouver la fonction Slick.prototype.slideHandler Dans son corps, remplacer l'appel

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

à

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

@ Maciej Kwas

C’est peut-être une fonctionnalité, mais sur ce site, lorsque vous regardez sur le curseur avec le "Mode Centre", l’animation semble correcte lorsque vous glissez de la dernière à la première diapositive . http://kenwheeler.github.io/ lisse/

0
Paweł Kwiatkowski