- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我使用 css @keyframes 创建了一个圆的基本动画。我正在使用 javascript 通过在圆圈内单击来触发动画开始/停止。
动画本身可以分为 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 , 通过:
The key must resolve to a number between 0 and 1, or the rule is ignored.
我假设在 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)
重现并删除所有规则(因为我预计索引会在每次删除规则后移动)。
现在,我想明白:
deleteRule
的正确方法是什么(基本上,'我做错了什么?')(或者是否应该使用其他方法)?最佳答案
What is the proper way (basically, 'Am I doing something wrong?') to use deleteRule in the IE (or if another method should be used)?
Why am I not able to delete more than two rules out of five?
第一个 MSDN 链接不适用; deleteRule()
方法适用于顶级规则,而不是关键帧规则。
文本“ key 必须解析为 0 到 1 之间的数字,否则规则将被忽略。”从第二个链接实际上取自 2013 WD of css-animations , 并且意味着 Internet Explorer 需要一个表示百分比的十进制数,而不是包含 0%-100% 关键帧选择器的字符串。该参数不代表索引。
因此对于 0% 关键帧规则,IE 期望值为 0;对于 100% 关键帧规则,IE 期望值为 1;对于 33.3% 的关键帧规则,IE 期望浮点值 0.333:
key_frame_list.deleteRule(0) // Deletes the 0% keyframe rule
key_frame_list.deleteRule(0.333) // Deletes the 33.3% keyframe rule
key_frame_list.deleteRule(1) // Deletes the 100% keyframe rule
删除 0% 规则后,如果没有 0% 规则保留,则对 deleteRule(0)
的额外调用将不会执行任何操作。
并且由于关键帧不能超过 100%,deleteRule(2)
没有意义,因为这意味着删除 200% 关键帧规则,而该规则不存在。
Is there a method suitable for this purposes that will work with the same arguments on Firefox, Chrome and IE11, I am not aware of?
没有; Internet Explorer 11 遵循 2013 WD(本身是在 Internet Explorer 10 发布后于 2012 年至 2013 年间开发的),这意味着它的实现与当前标准不一致,其中 the deleteRule()
method has been changed to accept a string argument instead of a numeric argument .
这意味着 API 不兼容,因此没有干净的解决方法。你只需要尝试这两个论点。我 changed您的 fiddle 中的以下语句:
// 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])
}
到:
// delete old rules
for(var i = 0; i < to_be_removed_key_list.length; i++) {
try {
key_frame_list.deleteRule(to_be_removed_key_list[i])
} catch (e) {
key_frame_list.deleteRule(+(parseFloat(to_be_removed_key_list[i]) / 100).toFixed(3))
}
}
+(parseFloat(to_be_removed_key_list[i])/100).toFixed(3)
位将百分比字符串转换为数值,并考虑舍入误差。 IEEE-754 float 固有的舍入误差是 API 最初发生变化的原因(这与始终需要字符串的 appendRule()
方法保持一致),除了因为它只是在 Internet Explorer 11 发布后 才更改,并且自 IE11 will no longer receive platform updates ,这意味着 IE11 坚持其旧的 WD 实现(我必须强调,在其开发时是最新的)。
关于javascript - IE11 中的 deleteRule CSSKeyframesRule 方法混淆行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46402020/
我正在遍历 CSS 关键帧,以便根据最接近动画元素当前行为的关键帧将原始动画更改为新动画。我使用下面的函数通过遍历样式表来获取关键帧规则。 function findKeyframesRule(rul
我使用 css @keyframes 创建了一个圆的基本动画。我正在使用 javascript 通过在圆圈内单击来触发动画开始/停止。 动画本身可以分为 5 个(循环)阶段: 暂停-扩展-暂停-收缩-
我是一名优秀的程序员,十分优秀!