[英]CSS fade not working in Chrome
I wrote this function in javascript: 我在javascript中写了这个函数:
function unhide(el, dur = 300, display = "block") {
el.style.display = display;
el.style.transitionDuration = dur + "ms";
el.style.opacity = 1;
}
For some reason, this isn't working in Chrome. 出于某种原因,这不适用于Chrome。
I remember having a problem like this, due to the browser not applying Javascript-written CSS atomically. 我记得有这样的问题,因为浏览器没有原子地应用Javascript编写的CSS。
So, I tried putting a break point after the display was changed: 所以,我尝试在显示更改后设置一个断点:
function unhide(el, dur = 300, display = "block") {
el.style.display = display;
● el.style.transitionDuration = dur + "ms";
el.style.opacity = 1;
}
This fixed the problem. 这解决了这个问题。
This same issue occurs in FireFox, but not Microsoft edge. 同样的问题出现在FireFox中,但不是Microsoft边缘。
How can I fix this? 我怎样才能解决这个问题?
Is there a way to force the browser to apply the display, and then the opacity? 有没有办法强制浏览器应用显示,然后是不透明度?
I just thought about using a setTimeout
( for setting the opacity, because, again, the display is not atomically applied ), however, that seems like a messy/inefficient hack. 我只是考虑使用
setTimeout
( 用于设置不透明度,因为再次,显示不是原子地应用 ),但是,这似乎是一个混乱/低效的黑客。
Minimal implementation with a requestAnimationFrame 使用requestAnimationFrame进行最少的实现
function unhide(el, dur = 1000, display = "block") { console.log("opacity when display none: ", getComputedStyle(mrHyde, null).opacity); el.style.display = display; console.log("opacity when display block: ", getComputedStyle(mrHyde, null).opacity) el.style.transitionDuration = dur + "ms"; requestAnimationFrame(() => el.style.opacity = 1); } const mrHyde = document.getElementById("unhideMe"); unhide(mrHyde);
#unhideMe { display: none; opacity: 0; }
<div id="unhideMe">Mr. Hyde</div>
EDIT I replaced setTimeout
with requestAnimationFrame
. 编辑我用
requestAnimationFrame
替换了setTimeout
。 The end result is the same but I feel requestAnimationFrame
is more suited for this purpose. 最终的结果是一样的,但我觉得
requestAnimationFrame
更适合这个目的。
EDIT 2 This behavior is actually already reported as a bug . 编辑2此行为实际上已报告为错误 。 The very last comment on the thread raises a hypothesis that I also was speculating on.
关于该主题的最后评论提出了一个我也在猜测的假设。 Perhaps the browser "discards" the numeric value of
opacity
when the element is in display: none
. 当元素处于
display: none
时,浏览器可能会“丢弃” opacity
的数值。 That would imply that setting the opacity: 1
does not trigger a css transition, because transitions only work on well defined style property values. 这意味着设置
opacity: 1
不会触发css转换,因为转换仅适用于定义良好的样式属性值。 On the very next event loop, the browser will have a defined opacity
value for the element, because it is by now in display: block
. 在下一个事件循环中,浏览器将为元素定义一个
opacity
值,因为它现在是display: block
。
I took a small step into proving this hypothesis by logging the computed style value of the element when it is in display: none
and right after it switches to display: block
. 我通过记录元素在
display: none
的计算样式值并在它切换到display: block
之后立即记录了这个假设。 Both values are actually a well defined numeric 0
, so this goes against the hypothesis. 这两个值实际上是一个明确定义的数字
0
,因此这与假设相反。
PS: http://caniuse.com/#feat=requestanimationframe Coverage for requestAnimationFrame
seems to be fairly acceptable as of 2017, including IE > 9 versions. PS: http :
requestAnimationFrame
自2017年起, requestAnimationFrame
覆盖范围似乎相当可接受,包括IE> 9版本。
As theorised, its been noted that the browser groups JS-applied CSS alterations together. 从理论上讲,已经注意到浏览器将JS应用的CSS变更组合在一起。
Is there a way to force the browser to apply the display, and then the opacity?`
有没有办法强制浏览器应用显示,然后是不透明度?`
Yes. 是。 Add the line:
添加行:
el.offsetWidth;
between the two CSS alterations. 两个CSS之间的变化。
This forces the browser to re-render the pages CSS. 这会强制浏览器重新呈现CSS页面。
var el = document.getElementById("hidden"); unhide(el); function unhide(el, dur = 300, display = "block") { el.style.display = display; el.style.transitionDuration = dur + "ms"; el.offsetWidth; el.style.opacity = 1; }
<div id="hidden" style="display: none; opacity: 0;">Unhidden</div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.