Запустить браузер, чтобы активировать оплату при изменении CSS.

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

Структура проста: видовое окно и внутри относительно позиционированного UL с левыми плавающими LI.

В такой ситуации я столкнулся с проблемой:

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

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

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

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

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/

Ответ 1

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

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

И назовите это, когда нужны рефлексии. См. Этот пример: http://jsfiddle.net/9WX5b/2/

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

Ответ 2

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

Он работает нормально с Chrome и FF и, по-видимому, является самым простым и самым портативным способом для этого ATM.