简体   繁体   English

使用javascript设置CSS动画延迟

[英]Set CSS animation delay with javascript

I have some keyframe animations in my css file. 我的css文件中有一些关键帧动画。 There is already an animation-delay specified. 已经指定了动画延迟。 The wrapper div has the attribute data-delay. 包装器div具有属性data-delay。

I want to get the animation-delay in the css file and add the value of data-delay to it. 我想在css文件中获取动画延迟并向其添加数据延迟的值。 Then i want that the animation start with the new delay. 然后我希望动画以新的延迟开始。

I tried ele[i].style.animationDelay . 我试过ele[i].style.animationDelay But it seems that this returns null until I set a value to it. 但似乎在我为其设置值之前返回null。

If I set ele[i].style.animationDelay = '5s' the animation still runs with the delay of the css file. 如果我设置ele[i].style.animationDelay = '5s' ,动画仍会以css文件的延迟运行。

HTML HTML

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

CSS 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 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/ http://jsfiddle.net/FHuKN/4/

I've only tested this on Mac 10.8 Chrome 25, Safari 6.0, and FF 18.0. 我只在Mac 10.8 Chrome 25,Safari 6.0和FF 18.0上进行了测试。

Sounds like the main thing you wanted to do was add the data-delay value to whatever existing animation delay was applied to the elements. 听起来你想要做的主要是将data-delay值添加到应用于元素的任何现有动画延迟。

HTML - unchanged HTML - 不变

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

CSS - Vendor prefixes and initial keyframes (0%) were added. 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 JAVASCRIPT

On an element, the style property doesn't hold all the style information because it only represents what is being set directly on the element via the style attribute. 在元素上, style属性不包含所有样式信息,因为它仅表示通过style属性直接在元素上设置的内容。 MDN MDN

window.getComputedStyle() seems to work pretty well. window.getComputedStyle()似乎工作得很好。

Juggling the prefixed properties is a little clunky, but it worked in the browsers I tested with. 杂耍前缀属性有点笨重,但它在我测试过的浏览器中有效。

(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/ http://jsfiddle.net/FHuKN/11/

Old Firefoxes (at least up to 16), Opera before migrating to Blink (<15), IE at least 10 - will not redraw the animation if we just change some of its attributes like (-prefix-)animation-delay . 旧的Firefox(至少16个),Opera迁移到Blink(<15),IE至少10个 - 如果我们只改变它的一些属性,如(-prefix-)animation-delay则不会重绘动画。 In order to make them do so, we have to apply some depper tricks. 为了让他们这样做,我们必须应用一些捣蛋技巧。

  1. The first will be removing and reinserting the animated element . 第一个是删除并重新插入动画元素 And - for the sake of Webkit - applying all the style changes on it. 并且 - 为了Webkit - 应用它上面的所有样式更改。

Just change the code from @tiffon's fiddle 只需从@ tiffon的小提琴中更改代码即可

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

To

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/ http://jsfiddle.net/FHuKN/28/

  1. Remove the class name ar the attribute value, which the animation is attached to, wait for a bit ( setTimeout ) of - better - trigger the reflow (say, element.offsetWidth = element.offsetWidth; ), and add the class name again. 删除类名称ar动画附加到的属性值,等待( setTimeout ) - 更好 - 触发重排(例如, element.offsetWidth = element.offsetWidth; ),然后再次添加类名。

http://jsfiddle.net/FHuKN/29/ http://jsfiddle.net/FHuKN/29/

The idea is not mine, all credit goes to Chris Coyer 这个想法不是我的,所有的功劳都归功于Chris Coyer

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM