使用javascript设置CSS动画延迟

时间:2012-12-08 22:03:34

标签: javascript css animation

我的css文件中有一些关键帧动画。已经指定了动画延迟。 包装器div具有属性data-delay。

我想在css文件中获取动画延迟并向其添加数据延迟的值。 然后我希望动画以新的延迟开始。

我试过了ele[i].style.animationDelay。 但似乎在我为它设置一个值之前返回null。

如果我设置ele[i].style.animationDelay = '5s',动画仍会以css文件的延迟运行。

HTML

<div id="wrapper" data-delay="2s" >
    <h1 id="hi">Hi</h1>
    <h1 id="name">test!</h1>
</div>

CSS

body { font-size: 300%; }

#wrapper h1 { position: absolute; }

#hi {
    transform: translate(-200px, 100px);

    animation-name: hi;
    animation-duration: .5s;
    animation-timing-function: linear;
    animation-fill-mode: forwards;
    animation-delay: 0s;
}

#name {
    transform: translate(-200px, 150px);

    animation-name: name;
    animation-duration: .5s;
    animation-timing-function: linear;
    animation-fill-mode: forwards;
    animation-delay: 1s;
}

@keyframes hi{
    100% { transform: translate(50px, 100px) };
}

@keyframes name{
    100% { transform: translate(50px, 150px) };
}

JS

var wrapper = document.getElementById('wrapper');
var ele = wrapper.children;
var delay = wrapper.getAttribute('data-delay');

for (var i=0;i<ele.length;i++) {

    alert(ele[i].style.animationDelay);
    ele[i].style.animationDelay = delay;
    alert(ele[i].style.animationDelay);
}

http://jsfiddle.net/FHuKN/4/

2 个答案:

答案 0 :(得分:5)

我只在Mac 10.8 Chrome 25,Safari 6.0和FF 18.0上进行了测试。

您想要做的主要事情是将data-delay值添加到应用于元素的任何现有动画延迟。

HTML - 未更改

<div id="wrapper" data-delay="5.1s" >
    <h1 id="hi">Hi</h1>
    <h1 id="name">test!</h1>
</div>

CSS - 添加了供应商前缀和初始关键帧(0%)。

body { font-size: 300%; }

#wrapper h1 { position: absolute; }

#hi { 
    -webkit-transform: translate(-200px, 100px);
    -webkit-animation-name: hi;
    -webkit-animation-duration: .5s;
    -webkit-animation-timing-function: linear;
    -webkit-animation-fill-mode: forwards;
    -webkit-animation-delay: 2.1s;

    -moz-transform: translate(-200px, 100px);
    -moz-animation-name: hi;
    -moz-animation-duration: .5s;
    -moz-animation-timing-function: linear;
    -moz-animation-fill-mode: forwards;
    -moz-animation-delay: 2.1s;

    transform: translate(-200px, 100px);
    animation-name: hi;
    animation-duration: .5s;
    animation-timing-function: linear;
    animation-fill-mode: forwards;
    animation-delay: 2.1s;
}

#name { 
    -webkit-transform: translate(-200px, 150px);
    -webkit-animation-name: name;
    -webkit-animation-duration: .5s;
    -webkit-animation-timing-function: linear;
    -webkit-animation-fill-mode: forwards;
    -webkit-animation-delay: 3.1s;

    -moz-transform: translate(-200px, 150px);
    -moz-animation-name: name;
    -moz-animation-duration: .5s;
    -moz-animation-timing-function: linear;
    -moz-animation-fill-mode: forwards;
    -moz-animation-delay: 3.1s;

    transform: translate(-200px, 150px);
    animation-name: name;
    animation-duration: .5s;
    animation-timing-function: linear;
    animation-fill-mode: forwards;
    animation-delay: 3.1s;
}

@-moz-keyframes hi{
    0% { -moz-transform: translate(-200px, 100px); }
    100% { -moz-transform: translate(50px, 100px); }
}
@-webkit-keyframes hi {
    0% { -webkit-transform: translate(-200px, 100px); }
    100% { -webkit-transform: translate(50px, 100px); }
}
@keyframes hi{
    0% { transform: translate(-200px, 100px); }
    100% { transform: translate(50px, 100px); }
}

@-moz-keyframes name {
    0% { -moz-transform: translate(-200px, 150px); }
    100% { -moz-transform: translate(50px, 150px); }
}
@-webkit-keyframes name {
    0% { -webkit-transform: translate(-200px, 150px); }
    100% { -webkit-transform: translate(50px, 150px); }
}
@keyframes name {
    0% { transform: translate(-200px, 150px); }
    100% { transform: translate(50px, 150px); }
}

JAVASCRIPT

在元素上,style属性不包含所有样式信息,因为它仅表示通过style属性直接在元素上设置的内容。 MDN

window.getComputedStyle()似乎运作良好。

处理前缀属性有点笨拙,但它在我测试的浏览器中有效。

(function(undefined) {

    var wrapper = document.getElementById('wrapper'),
        elms = wrapper.children,
        delay = wrapper.getAttribute('data-delay'),
        prop,
        styl,
        cur,
        i;

    delay = !delay ? 0 : Number(delay.replace(/[^\d\.]/g, ''));

    if (!elms.length) {
        return;
    }

    styl = window.getComputedStyle(elms[0]);

    if (styl.getPropertyValue('animation-delay')) {
        prop = 'animation-delay';

    } else if (styl.getPropertyValue('-webkit-animation-delay')) {
        prop = '-webkit-animation-delay';

    } else if (styl.getPropertyValue('-moz-animation-delay')) {
        prop = '-moz-animation-delay';

    } else {
        console.log('unable to find prop');
        return;
    }
    // console.log('prop', prop);

    for (i = 0; i < elms.length; i++) {
        styl = window.getComputedStyle(elms[i]);
        cur = styl.getPropertyValue(prop);
        cur = Number(cur.replace(/[^\d\.]/g, ''));
        elms[i].style.setProperty(prop, (cur + delay) + 's');

        console.log('delay: ' + cur + 's -> ' + (cur + delay) + 's')
    }

})();

http://jsfiddle.net/FHuKN/11/

答案 1 :(得分:0)

旧的Firefox(至少16个),Opera迁移到Blink(&lt; 15),IE至少10个 - 如果我们只改变它的一些属性,如(-prefix-)animation-delay,则不会重绘动画。为了让他们这样做,我们必须应用一些捣蛋技巧。

  1. 第一个是删除并重新插入动画元素。并且 - 为了Webkit - 应用它上面的所有样式更改。
  2. 只需更改@ tiffon小提琴的代码

    elms[i].style.setProperty(prop, (cur + delay) + 's');
    

    var newEl =  elms[i].cloneNode(true);
    newEl.style.setProperty(prop, (cur + delay) + 's', '');
    elms[i].parentNode.replaceChild(newEl,elms[i]);
    

    http://jsfiddle.net/FHuKN/28/

    1. 删除类名和附加动画的属性值,等待(setTimeout) - 更好 - 触发重排(比如element.offsetWidth = element.offsetWidth;),并添加班级名称。
    2. http://jsfiddle.net/FHuKN/29/

      这个想法不是我的,所有的功劳归于Chris Coyer