使用 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
Set CSS animation delay with javascript
提问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);
}
回答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-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
爪哇脚本
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. 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')
}
})();
回答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技巧。
- 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'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]);
- 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.
- 删除动画所附加的属性值的类名,等待(
setTimeout
) - 更好 - 触发回流(例如,element.offsetWidth = element.offsetWidth;
),然后再次添加类名。
The idea is not mine, all credit goes to Chris Coyer
这个想法不是我的,所有功劳都归功于Chris Coyer