CSS-переход не запускается - PullRequest
       27

CSS-переход не запускается

24 голосов
/ 15 августа 2011

Я создаю элемент DOM (div), добавляю его в DOM, затем меняю его ширину одним быстрым нажатием в javascript. Теоретически это должно инициировать переход CSS3, но результат будет прямым от A к B, без перехода между ними.

Если я изменю ширину с помощью отдельного события щелчка для теста, все будет работать как положено.

Вот мой JS и CSS:

JS (jQuery):

var div = $('<div />').addClass('trans').css('width', '20px');
$('#container').append(div);
div.css('width', '200px');

CSS (просто mozilla на минуту):

.trans {
    -moz-transition-property: all;
    -moz-transition-duration: 5s;
    height: 20px;
    background-color: cyan;
}

Я тут все испортил, или «быстрый удар все-в-одном» - это не то, что нужно делать?

Вся помощь очень ценится.

Ответы [ 6 ]

44 голосов
/ 11 ноября 2013

Более чистый подход, который не основан на setTimeout, заключается в чтении соответствующего свойства css перед его установкой:

var div = $('<div />').addClass('trans');
$('#container').append(div);
div.css('width');//add this line
div.css('width', '200px');

Работает здесь:

http://jsfiddle.net/FYPpt/144/

Как поясняется в комментариях ниже от Lucero, для этого необходимо заставить браузер вычислять фактическое значение, а не «авто», «наследовать» или подобное. Без действительного значения браузер не будет знать, что новое значение будет изменением по сравнению с предыдущим.

21 голосов
/ 16 августа 2011

вот два способа сделать это.

1 - переходы CSS

с помощью setTimeout будет запущен метод addClass, а не вместе с предыдущим сценарием, так что событие transition вызовет

пример jsfiddle

JQuery:

var div = $('<div class="trans" />');
$('#container').append(div);
// set the class change to run 1ms after adding the div
setTimeout(function() {div.addClass('wide')}, 1); 

CSS:

.trans {
    width: 20px;
    height: 20px;
    background-color: cyan;
    -webkit-transition: all 5s ease;
       -moz-transition: all 5s ease;
        -ie-transition: all 5s ease;
         -o-transition: all 5s ease;
            transition: all 5s ease;
}
.wide {
    width: 200px;
}

2 - функция jQuery .animate()

пример jsfiddle

JQuery:

var div = $('<div class="trans" />');
$('#container').append(div);
div.animate({'width': '200px'}, 5000); // 5 sec animation

CSS:

.trans {
    width: 20px;
    height: 20px;
    background-color: cyan;
}
5 голосов
/ 10 декабря 2014

Попробуйте вызвать метод jQuery .offset().

Когда браузер получает смещение, он запускает событие reflow / repaint / layout, которое позволяет переходам работать.

См. Эту скрипку:http://jsfiddle.net/FYPpt/199/

Также см. - http://gent.ilcore.com/2011/03/how-not-to-trigger-layout-in-webkit.html

3 голосов
/ 11 декабря 2014

В ответ на щедрость:

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

Причина, по которой setTimeout работает в первую очередь, связана с тем, что вы тем временем вызываете полное переиздание документа, даже если для длительности установлено значение 0. Это не единственный способ вызвать оплавление.


Ссылка на скрипку

JavaScript

for (x = Math.ceil(Math.random() * 10), i=0;i<x;i++){
    $('<div />').appendTo($('#container')).addClass('trans');
}

var divs = $('#container div');
var x = divs.eq(Math.ceil(Math.random() * divs.length));
x[0].offsetHeight;
x.addClass('wide');

С помощью этого JavaScript мы случайным образом добавляем от 1 до 10 div элементов, а затем выбираем один из них случайным образом и добавляем класс wide.

Там вы увидите странную строку JavaScript, а именно x[0].offsetHeight. Это основа всей операции. Вызов offsetHeight вызывает переформатирование документа без использования setTimeout или запроса значения CSS.

Что такое перекомпоновка по отношению к DOM:

Перекомпоновка вычисляет макет страницы. Перекомпоновка элемента пересчитывает размеры и положение элемента, а также запускает дальнейшие переливы на детей, предков и элементов этого элемента элементы, которые появляются после него в DOM. Тогда это вызывает финал перекрашивать. Переплата очень дорогая, но, к сожалению, это может быть срабатывает легко.

Поэтому, пожалуйста, будьте осмотрительны в том, как вы используете эти функции. Не слишком беспокоит большинство современных браузеров (так как jQuery известен тем, что запускает несколько перефразировок), но все же стоит подумать, прежде чем добавлять что-то вроде этого решения на ваш сайт.


Важное примечание: Это не более или менее эффективный, чем setTimeout звонок . Это не решение волшебной пули, и оно делает то же самое под капотом.


Вот соответствующий CSS, для справки:

.trans {
    width: 20px;
    height: 20px;
    background-color: cyan;
    -webkit-transition: all 5s ease;
       -moz-transition: all 5s ease;
         -o-transition: all 5s ease;
            transition: all 5s ease;
}

.trans.wide {
    width: 200px;
}
2 голосов
/ 10 декабря 2014

как спрашивал @onetrickpony, что если все правила находятся в файле CSS и не должны добавляться в JS-функцию.

На основании ответа Торина Финнеманна, с небольшим изменением:

Добавить дополнительный класс, в котором определены правила: new-rules

var div = $('<div class="trans" />');
$('#container').append(div);

var div = $('<div />').addClass('trans');
$('#container').append(div);
div.height();
div.addClass('new-rules');

в вашем CSS есть предопределенный класс:

.trans.new-rules {
    width: 200px;
    background: yellow;
}

теперь нет необходимости покалывать JS при изменении CSS. Измените его в CSS-файле на new-rules:)

http://jsfiddle.net/FYPpt/201/

1 голос
/ 12 декабря 2014
var div = $('<div />');

$('#container').append(div);

div.css('width', '20px').addClass('trans', function() {
   div.css('width', '200px') 
});

Создает новый элемент DIV и добавляет класс 'trans' к этому элементу для запуска перехода CSS

...