Переходы CSS не работают при назначении JavaScript
У меня возникает серьезная головная боль, пытающаяся применить переходы CSS3 к слайд-шоу через JavaScript.
В основном JavaScript получает все слайды в слайд-шоу и применяет классы CSS к правильным элементам, чтобы придать приятный анимированный эффект, если поддержка CSS3 не поддерживается, он будет применять стили без перехода.
Теперь моя "маленькая" проблема. Все работает, как и ожидалось, все слайды получают правильные стили, код работает без ошибок (пока). Но указанные переходы не работают, даже если правильные стили применяются. Кроме того, стили и переходы работают, когда я сам применяю их через инспектора.
Поскольку я не мог найти логическое объяснение, я подумал, что кто-то здесь может ответить на него, пожалуйста, пожалуйста?
Я собрал небольшой пример того, что код сейчас: http://g2f.nl/38rvma
Или используйте JSfiddle (без изображений): http://jsfiddle.net/5RgGV/1/
Ответы
Ответ 1
Чтобы сделать работу transition
, должно произойти три вещи.
- элемент должен иметь явное определение свойства, в этом случае:
opacity: 0;
- элемент должен иметь определенный переход:
transition: opacity 2s;
- необходимо установить новое свойство:
opacity: 1
Если вы назначаете 1 и 2 динамически, как и в вашем примере, должна быть задержка до 3, чтобы браузер мог обработать запрос. Причина, по которой он работает, когда вы отлаживаете это, заключается в том, что вы создаете эту задержку, пройдя через нее, предоставляя время браузера для обработки. Дайте задержку для назначения .target-fadein
:
window.setTimeout( function() { slides[targetIndex].className += " target-fadein"; }, 100 );
Или поместите .target-fadein-begin
в свой HTML напрямую, чтобы он разобрался с загрузкой и будет готов к переходу.
Добавление transition
к элементу не является тем, что запускает анимацию, изменяя свойство.
Демо: http://jsfiddle.net/ThinkingStiff/QNnnQ/
HTML:
<div id="fade1" class="fadeable">fade 1 - works</div>
<div id="fade2">fade 2 - doesn't work</div>
<div id="fade3">fade 3 - works</div>
CSS:
.fadeable {
opacity: 0;
}
.fade-in {
opacity: 1;
transition: opacity 2s;
-moz-transition: opacity 2s;
-ms-transition: opacity 2s;
-o-transition: opacity 2s;
-webkit-transition: opacity 2s;
}
Script:
//works
document.getElementById( 'fade1' ).className += ' fade-in';
//doesn't work
document.getElementById( 'fade2' ).className = 'fadeable';
document.getElementById( 'fade2' ).className += ' fade-in';
//works
document.getElementById( 'fade3' ).className = 'fadeable';
window.setTimeout( function() {
document.getElementById( 'fade3' ).className += ' fade-in';
}, 100);
Ответ 2
Ниже приведен пример (JSFiddle) перехода на затухание, работающий над триггером Javascript.
Ответ 3
Обманите механизм компоновки!
function finalizeAndCleanUp (event) {
if (event.propertyName == 'opacity') {
this.style.opacity = '0'
this.removeEventListener('transitionend', finalizeAndCleanUp)
}
}
element.style.transition = 'opacity 1s'
element.style.opacity = '0'
element.addEventListener('transitionend', finalizeAndCleanUp)
// next line important but there no need to store the value
element.offsetHeight
element.style.opacity = '1'
Как уже упоминалось, transition
работает путем интерполяции из состояния A в состояние B. Если ваш script вносит изменения в одну и ту же функцию, механизм компоновки не может отделяться от состояния A и начинается B. Если вы не дадите ему намек.
Поскольку нет официального способа сделать намек, вы должны полагаться на побочные эффекты некоторых функций. В этом случае .offsetHeight
getter, который неявно заставляет механизм компоновки останавливаться, оценивать и вычислять все установленные свойства и возвращать значение. Как правило, этого следует избегать при оценке производительности, но в нашем случае это именно то, что необходимо: консолидация состояния.
Код очистки добавлен для полноты.
Ответ 4
Некоторые люди спрашивают, почему происходит задержка. Стандарт хочет разрешить сразу несколько переходов, известных как событие изменения стиля (например, элемент замирает в то же время, когда он вращается в представлении). К сожалению, он не определяет явный способ группировки переходов, которые вы хотите совершить одновременно. Вместо этого он позволяет браузерам произвольно выбирать, какие переходы происходят одновременно с тем, насколько они выходят друг от друга. Большинство браузеров, похоже, используют свою частоту обновления, чтобы определить это время.
Вот стандарт, если вы хотите получить более подробную информацию:
http://dev.w3.org/csswg/css-transitions/#starting