将元素的属性强制为某个值,即使它正在被动画化
Posted
技术标签:
【中文标题】将元素的属性强制为某个值,即使它正在被动画化【英文标题】:Force a property of an element to a certain value even as it's being animated 【发布时间】:2017-09-12 06:21:50 【问题描述】:我有两种元素,我们称它们为.a
和.b
。
他们可能设置了一些 CSS 动画。我无法控制这些关键帧、它们是否已设置以及它们正在制作的动画。
他们可能正在为opacity
制作动画。但是,我希望我的.a
元素上的opacity
保持一定的值,比如说1
,不管它是否是动画的。
考虑下面的代码,我有三种情况:
-
我的元素上没有设置动画
有动画,但没有动画
opacity
有一个动画,opacity
是动画属性之一
div
/* some dummy styles so we can see stuff */
display: inline-block;
width: 5em; height: 5em;
background: purple;
[class*='ani'] animation: a 1s ease-out infinite alternate
.ani--one animation-name: ani-one
@keyframes ani-one to transform: scale(.5)
.ani--two animation-name: ani-two
@keyframes ani-two
to
opacity: 0;
background: orange;
<div class='a'></div>
<div class='b'></div>
<div class='a ani--one'></div>
<div class='b ani--one'></div>
<div class='a ani--two'></div>
<div class='b ani--two'></div>
在前两种情况下(1 = 没有关键帧动画,2 = 关键帧动画,但它不是动画opacity
)我不需要做任何事情。
然而,在最后一种情况下,我需要以某种方式将.a
元素的opacity
强制为1
,取消对那个属性的动画效果。
我无法从.a
元素中删除关键帧动画,因为我希望其他属性(在本例中为background
,在一般情况下可能是其他属性)继续进行动画处理。
我无法更改动画,因为我希望它按最初指定的方式工作,为其他元素 (.b
) 设置动画 opacity
。
所以问题是,我如何检测.a
元素上的opacity
属性是否正在动画,如果是,我如何强制其值保持在1
,而通过相同关键帧设置的其他属性正在被动画化?
我想用 vanilla JS 解决这个问题,没有库。
【问题讨论】:
while(true)elem.opacity=1; 但那很 hacky... 【参考方案1】:您可以使用 !important 破解它
.solid-always opacity:1 !important;
然后在课堂上放入你不希望其不透明度改变的那个。关键帧不应覆盖 !important。
【讨论】:
实际上,@keyframe
动画 do 会覆盖 !important
,他们应该按照规范这样做。试试看吧。
抱歉,但按照规范,“重要作者声明”级联起源应该覆盖“动画声明”(w3.org/TR/css-cascade-4/#cascading),所以理论上,@Noobit 的回答基本上是正确的.问题是该规范多年来仅在 Firefox 中正确实施。但最近这个错误已在 Chromium (bugs.chromium.org/p/chromium/issues/detail?id=552085) 中得到修复【参考方案2】:
现在我突然想到,我可以通过添加额外的 CSS 关键帧动画来做到这一点:
@keyframes opacity-override 0%, 100% opacity: 1
现在对于所有设置了animation
的.a
元素,我可以将opacity-override
添加到动画名称中,它应该会处理好事情!
此外,我可以使用它来强制opacity: 1
反对可能在悬停或添加其他类时设置的样式,这非常方便!
const _A = document.querySelectorAll('.a');
_A.forEach(a =>
let aname = getComputedStyle(a).animationName;
if(aname !== 'none') a.style.animationName = `$aname, opacity-override`;
else a.style.animation = 'opacity-override 1s infinite';
);
div
/* some dummy styles so we can see stuff */
display: inline-block;
width: 5rem; height: 5rem;
background: purple;
color: white;
font: 700 3em/5rem verdana;
text-align: center;
div:hover opacity: .7
[class*='ani'] animation: a 1s ease-out infinite alternate
.ani--one animation-name: ani-one
@keyframes ani-one to transform: scale(.5)
.ani--two animation-name: ani-two
@keyframes ani-two
to
opacity: 0;
background: orange;
@keyframes opacity-override 0%, 100% opacity: 1
<div class='a'>A</div>
<div class='b'>B</div>
<div class='a ani--one'>A</div>
<div class='b ani--one'>B</div>
<div class='a ani--two'>A</div>
<div class='b ani--two'>B</div>
【讨论】:
以上是关于将元素的属性强制为某个值,即使它正在被动画化的主要内容,如果未能解决你的问题,请参考以下文章