使用 javascript 设置 CSS 动画延迟

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13782407/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 19:45:33  来源:igfitidea点击:

Set CSS animation delay with javascript

javascriptcssanimation

提问by tryzor

I have some keyframe animations in my css file. There is already an animation-delay specified. The wrapper div has the attribute data-delay.

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

I want to get the animation-delay in the css file and add the value of data-delay to it. Then i want that the animation start with the new delay.

我想在css文件中获取animation-delay并将data-delay的值添加到它。然后我希望动画以新的延迟开始。

I tried ele[i].style.animationDelay. But it seems that this returns null until I set a value to it.

我试过了ele[i].style.animationDelay。但在我为其设置值之前,这似乎返回 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/

回答by tiffon

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-delayvalue 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

爪哇脚本

On an element, the styleproperty doesn't hold all the style information because it only represents what is being set directly on the element via the styleattribute. MDN

在元素上,style属性不包含所有样式信息,因为它仅表示通过style属性直接在元素上设置的内容。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/

回答by bonflash

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. In order to make them do so, we have to apply some depper tricks.

旧的 Firefox(至少 16 个),迁移到 Blink 之前的 Opera(<15),IE 至少 10 个 - 如果我们只是改变它的一些属性,比如(-prefix-)animation-delay. 为了让他们这样做,我们必须应用一些depper技巧。

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

Just change the code from @tiffon's fiddle

只需更改@tiffon's fiddle 中的代码

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.
  1. 删除动画所附加的属性值的类名,等待(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