我用css @keyframes创建了一个圆的基本动画。 我使用javascript通过点击圆圈内部触发动画开始/停止。deleteRule CSSKeyframesRule方法在IE11中混淆了行为
动画本身可分为5(环形)阶段:
暂停扩大暂停收缩暂停(见下文@keyframes CSS部分)
我想达到的目标是,最终,能够设置动画持续时间并改变关键帧的值(比如通过输入字段来暂停和展开/缩小持续时间 - 细节对于这个问题的范围并不重要)。为了测试它的工作原理,我编写了一个JavaScript函数来执行此任务,并将其设置为onload
。
我的HTML:
<!doctype html>
<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<link rel="stylesheet" href="style.css">
<script src = "animation.js"></script>
</head>
<body onload=setAnimationDuration(1,1)>
<div id="circle" class='circle-paused' onclick=cssAnimation()></div>
</body>
</html>
我的CSS:
#circle {
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
}
.circle-paused {
width: 9%;
padding-top: 9%;
border-radius: 50%;
background-color: #800080;
margin: auto;
}
.circle-animated {
/* 2 sec pause 4 sec expand_shrink*/
width: 9%;
padding-top: 9%;
-webkit-animation-name: my-circle; /* Safari 4.0 - 8.0 */
-webkit-animation-duration: 12s; /* Safari 4.0 - 8.0 */
animation-name: my-circle;
animation-duration: 12s;
animation-iteration-count: infinite;
animation-timing-function: linear;
border-radius: 50%;
margin: auto;
}
@keyframes my-circle {
0% {background-color: #800080; width: 9%; padding-top: 9%;}
33.3% {background-color: #D8BFD8; width: 28%; padding-top: 28%;}
50% {background-color: #D8BFD8; width: 28%; padding-top: 28%;}
83.3% {background-color: #800080; width: 9%; padding-top: 9%;}
100% {background-color: #800080; width: 9%; padding-top: 9%;}
}
我的javascript:
function cssAnimation() {
if (document.getElementById('circle').className == 'circle-paused') {
document.getElementById('circle').className = 'circle-animated'
} else {
document.getElementById('circle').className = 'circle-paused'
}
}
function findKeyframes(animation_name) {
// get list of current keyframe rules
var style_sheet = document.styleSheets;
for (var i = 0; i < style_sheet.length; ++i) {
for (var j = 0; j < style_sheet[i].cssRules.length; ++j) {
// type 7 correspond to CSSRule.KEYFRAMES_RULE, for more info see https://developer.mozilla.org/en-US/docs/Web/API/CSSRule
if (style_sheet[i].cssRules[j].type == 7 && style_sheet[i].cssRules[j].name == animation_name) {
return style_sheet[i].cssRules[j];
}
}
}
// keyframe rules were not found for given animation_name
return null;
}
function getPercentage(total, fraction) {
// Returns what percentage the fraction is from total
// The result is rounded to 1 decimal place
return Math.round(((100/total) * fraction) * 10)/10;
}
function setAnimationDuration(pause, expand_shrink) {
var total_animation_duration = (pause * 2) + (expand_shrink * 2)
var pause_percentage = getPercentage(total_animation_duration, pause)
var expand_shrink_percentage = getPercentage(total_animation_duration, expand_shrink)
var pause1 = pause_percentage + expand_shrink_percentage;
var shrink = pause1 + expand_shrink_percentage;
var frame_percentage_list = [0, expand_shrink_percentage, pause1, shrink, 100]
var key_frame_list = findKeyframes('my-circle')
var new_rule_list = []
var to_be_removed_key_list = []
//create array of new rules to be inserted
//collecting old keys of rules to be deleted
for(var i = 0; i < key_frame_list.cssRules.length; i++) {
var current_rule = key_frame_list.cssRules[i].cssText
to_be_removed_key_list.push(key_frame_list.cssRules[i].keyText)
new_rule_list.push(current_rule.replace(/[+-]?([0-9]*[.])?[0-9]+%/, frame_percentage_list[i] + '%'))
}
// delete old rules
for(var i = 0; i < to_be_removed_key_list.length; i++) {
key_frame_list.deleteRule(to_be_removed_key_list[i])
}
// populate new ruels
for(var i = 0; i < new_rule_list.length; i++) {
key_frame_list.appendRule(new_rule_list[i])
}
document.getElementById('circle').style.animationDuration = total_animation_duration + "s"
}
问题本身:
代码在FireFox(55.0.3),Chrome(61.0)和Safari(11.0)中按预期工作。虽然,当我开始在IE11中测试它时,我发现key_frame_list.deleteRule('rule_key')
会引发Invalid argument
错误。在研究这个问题的过程中,我发现(并进入低谷)this article(尽管它没有解决IE问题,但它提高了我对css动画的整体理解)。在MSDN上,我找到两个参考文献,涉及deleteRule
:one和two。虽然我并没有真正理解什么意思,在the second one,通过:
的关键必须解析为数字0和1之间,或规则将被忽略。
我认为在IE中你必须将索引传递给deleteRule
而不是字符串键。所以我试图在IE控制台中检查我的假设。以下是我已经发现(给我的js代码是在onload事件):
var key_frame_list = findKeyframes('my-circle')
key_frame_list.cssRules.length => 5
key_frame_list.deleteRule(0)
key_frame_list.cssRules.length => 4
key_frame_list.deleteRule(1)
key_frame_list.cssRules.length => 3
key_frame_list.deleteRule(0)
key_frame_list.deleteRule(1)
key_frame_list.deleteRule(2)
...
key_frame_list.cssRules.length => 3
正在发生的事情是:
key_frame_list.deleteRule(0)
- 删除第一条规则(即0%)
key_frame_list.deleteRule(1
) - 删除最后一条规则(即100%)
之后,无论我传递给key_frame_list.deleteRule()
该指数key_frame_list.cssRules.length
保持3
我的期望是,我将能够与key_frame_list.deleteRule(0)
复发并删除所有规则(因为我预计索引将在每次删除规则后发生变化)。现在
,我想明白了:
- 什么是正确的方式(基本上,“?难道我做错了什么”)在IE使用
deleteRule
(或是否应使用另一种方法) ? - 为什么我无法删除五个以上的两个规则?
- 有没有一种方法适用于这个目的,将在Firefox,Chrome和IE11上使用相同的参数,我不知道?