@colorkid

Слайдер на JS. Странности с transition. Как быть?

Все привет.
Вот слайдер codepen.io/anon/pen/ZQorow
Суть проблемы в след:
Если переключаться между 1 и любым другим слайдом то все ок, все происходит плавно, и исчезает плавно и появляется новый слайд плавно. Также все нормально когда переключаюсь со второго на первый.
Но если переключиться с любого кроме первого (и не со второго на первый) то слайд который был, резко пропадает, получается как такая вспышка резкая. А я хочу что-бы все было плавно как между первм и вторым слайдами.

Как быть? Что править в коде? Куда смотреть?
  • Вопрос задан
  • 1277 просмотров
Решения вопроса 1
lazalu68
@lazalu68
Salmon
У вас верстка слайдера организована немного странно, поэтому чтобы исправить это не изменяя верстки, придется немного усложнить JS.

Видимый слайд у вас имеет "position: absolute" и по этому поводу занимает верхний слой над остальным контентом родителя, остальные слайды последовательно выстроены в вертикальный ряд и спрятаны с помощью "visibility: hidden; opacity: 0;". Так как к свойству "position" нельзя применить transition, когда вы переключаете слайд, текущий слайд сразу же получает "position: relative" и занимает свое место в вертикальном строю, а целевой слайд сразу же получает "position: absolute" и выскакивает на место предыдущего. То есть при переключении текущий слайд моментально исчезает, после чего сразу же становится виден первый видимый в ряду слайд (который прозрачный), а целевой слайд занимает top-овый слой и ему остается еще целая секунда, чтобы получить 100% opacity То есть в вашем варианте при каждом переключении пользователь видит три слайда: текущий, потом первый видимый в ряду и только потом - целевой. Отсюда и возникает эффект плавного перехода когда вы переключаетесь с 1 на любой другой или со 2 на 1: в этих случаях нету промежуточно видимого слайда, их участвует только двое, поэтому переход получается плавный.

В целом, я бы для начала поменял верстку как-нибудь) Тогда все будет просто.

Но если вы религиозно придерживаетесь вашей собственной верстки, то для нее я придумал такой вариант решения: разделить свойства класса .show на те, которые нужно анимировать, и на те, которые не нужно анимировать, и не анимируемые снимать со слайдов только в конце анимации, чтобы во время переключения в верхнем слое было два видимых слайда. Получилось так:

.slider_artists .show {
  opacity: 1;
}
.slider_artists .position {
  position: absolute;
  top: 0;
  left: 0;
}


При переключении целевой слайд получает сразу два класса - .show и .position, а текущий лишается сначала класса .show, а потом и .position, когда отыграется анимированный переход к дефолтным для img стилям. Последнее можно было сделать, например, добавив для слайдов eventListener на transitionend, который будет убирать класс .position c текущего элемента (хотя еще можно было по клику на control не только убирать класс .show, а еще оставлять setTimeout для текущего элемента на 1000 миллисекунд, который также будет убирать класс .position). Как-то так:

for(var i = 0; i < sliderLength.length; i++){
  sliderLength[i].addEventListener("transitionend", function() {
    if (!hasClass(this,'show')) {
      this.classList.remove('position');
    }
  }, false);
}


Готовый вариант на codepen.io

PS: А таки зачем вы сначала указываете transition для всех img, а потом еще раз его указываете для .show ?) Таки в момент когда img получает .show, он уже имеет нужный transition)
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы