Переходы CSS3 к динамически создаваемым элементам

Я пытаюсь анимировать динамически созданный html-элемент с помощью переходов CSS3.

Я хочу, чтобы анимация начиналась непосредственно перед созданием элемента.
Для этого я создаю класс, который устанавливает исходную позицию элемента, а затем я устанавливаю целевую позицию с помощью jquery css() метод

Но новый элемент просто появляется в целевой позиции без какого-либо перехода.

Если я использую setTimeout 0 мс, чтобы установить новое значение css, оно сработает.

Я что-то делаю не так? или это ограничение? Я не думаю, что мне нужно использовать обходной путь setTimeout.

Спасибо!

ОБНОВЛЕНИЕ. Вот ссылка на код, работающий на jsfiddle.net, для экспериментов. http://jsfiddle.net/blackjid/s9zSH/

ОБНОВЛЕНИЕ Я обновил пример решением в ответе.
http://jsfiddle.net/s9zSH/52/

Вот полностью рабочий пример кода

<html>
    <head>
        <script src="http://code.jquery.com/jquery-1.4.3.min.js"></script>
        <script type="text/javascript">

        //Bind click event to the button to duplicate the element
        $(".duplicate").live("click", function (e){
            var $to = $("#original .square").clone()
            $("body").append($to);
            if($(e.target).hasClass("timeout"))
                //With setTimeout it work
                setTimeout(function() {
                    $to.css("left", 200 + "px");
                },0);
            else if($(e.target).hasClass("notimeout"))
                // These way it doesn't work
                $to.css("left", 200 + "px");
        });

        </script>
        <style type="text/css">
        .animate{
            -webkit-transition: all 1s ease-in;
        }
        .square{
            width:50px;
            height:50px;
            background:red;
            position:relative;
            left:5px;
        }
        </style>
    </head>
    <body>
        <div id="original">
            <div class="square animate"></div>
        </div>

        <button class="duplicate timeout">duplicate with setTimeout</button>
        <button class="duplicate notimeout">duplicate without setTimeout</button>
    </body>
</html>

person blackjid    schedule 19.10.2010    source источник


Ответы (1)


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

Скорее, вы можете просто:

obj.className = style1;
window.getComputedStyle(obj).getPropertyValue("top");
obj.className = style2;

Если вы анимируете несколько объектов, вам нужно только один раз "прокачать" калькулятор стилей:

obj.className = style1;
obj2.className = style1;
obj3.className = style1;
window.getComputedStyle(obj).getPropertyValue("top");

obj.className = style2;
obj2.className = style2;
obj3.className = style2;

Протестировано в chrome12 на Mac

person mmaclaurin    schedule 02.08.2011
comment
дополнение: хотя вам не нужно использовать тайм-аут, иногда это может быть хорошо. это действительно зависит от вашего приложения. частый принудительный синхронный пересчет стилей может привести к заиканию пользовательского интерфейса. если вы обнаружите, что это происходит, разумно используйте тайм-аут, чтобы разбить/амортизировать сложную анимацию на несколько кадров. - person mmaclaurin; 20.06.2012
comment
Спасибо, это первое объяснение, которое я нашел, почему setTimeout эффективен для форсирования переходов CSS. - person B. Striegel; 07.05.2013
comment
Вау, здорово! Вы спасли мой день. Потерял довольно много времени, чтобы выяснить причину, наконец, вы решили ее. еще раз спасибо! - person Cam Song; 03.09.2014