Заставить браузер запускать reflow при изменении CSS

Я создаю не-jQuery отзывчивый слайдер изображения на основе переходов CSS3.

структура проста: viewport и внутренность относительно расположили UL с левым плавали LIs.

я сталкиваюсь с проблемой в такой ситуации:

  1. пользователь нажимает стрелку" prev".
  2. JS добавляет правильный LI перед текущим отображаемым узлом LI.
  3. на данный момент UL установил переход CSS как none 0s linear чтобы предотвратить изменения анимации. В этот момент я уменьшите значение UL CSS слева по ширине слайдера (скажем: от 0px до-1200px), чтобы сделать вид таким же, как был.
  4. теперь я изменяю свойство перехода UL на all 0.2s ease-out.
  5. теперь я изменяю левое свойство UL для запуска анимации CSS3. (скажем: от 1200px до 0px).

в чем проблема? Браузер упрощает изменения и не делает никаких анимаций.

Стоян Стефанов написал о проблеме reflow в своем блоге здесь, но в этом случае попытка заставить reflow на элементе не работает.

это часть кода делает это (я пропустил префиксы браузера для упрощения):

ul.style.transition = 'none 0s linear 0s'; ul.style.left = '-600px'; ul.style.transition = 'all 0.2s ease-out'; ul.style.left = '0px';

вот скрипка, чтобы увидеть проблему в действии:http://jsfiddle.net/9WX5b/1/

2 ответов


С просьбой offsetHeight элемента делает все красиво. Вы можете заставить reflow с помощью этой функции и передать ему элемент, стили которого были изменены на:

function reflow(elt){
    console.log(elt.offsetHeight);
}

и вызовите это, где необходимы отражения. См. этот пример:http://jsfiddle.net/9WX5b/2/

EDIT: недавно нужно было сделать это, и задавался вопросом, есть ли лучший способ, чем консоль.журнал. Вы не можете просто написать elt.offsetHeight как собственное утверждение, как оптимизатор (Chrome, по крайней мере) не вызовет reflow, потому что это просто доступ к свойству без набора геттеров, нет необходимости даже оценивать его. Итак, AFAIK самый дешевый способ сделать это -void(elt.offsetHeight), так как он не знает наверняка, если void есть побочные эффекты или нет. (может быть переопределен или что-то еще, idk).


function reflow( element ) {
    if ( element === undefined ) {
        element = document.documentElement;
    }
    void( element.offsetHeight );
}

он работает нормально с Chrome и FF и кажется самым простым и портативным способом сделать это ATM.