我在javascript中写了这个函数:
function unhide(el, dur = 300, display = "block") {
el.style.display = display;
el.style.transitionDuration = dur + "ms";
el.style.opacity = 1;
}
出于某种原因,这不适用于Chrome。
我记得有这样的问题,因为浏览器没有原子地应用Javascript编写的CSS。
所以,我尝试在显示改变后设置一个断点:
function unhide(el, dur = 300, display = "block") {
el.style.display = display;
● el.style.transitionDuration = dur + "ms";
el.style.opacity = 1;
}
这解决了问题。
同样的问题出现在FireFox中,但不是Microsoft边缘。
我该如何解决这个问题?
有没有办法强制浏览器应用显示,然后是不透明度?
我只是想过使用setTimeout
(来设置不透明度,因为再次显示不是原子应用),但是,这似乎是一个混乱/低效的黑客攻击。
答案 0 :(得分:2)
使用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>
修改强>
我将setTimeout
替换为requestAnimationFrame
。最终结果是一样的,但我觉得requestAnimationFrame
更适合这个目的。
编辑2
实际上,此行为已报告为bug。关于该主题的最后评论提出了一个我也在猜测的假设。当元素位于opacity
时,浏览器可能会“丢弃”display: none
的数值。这意味着设置opacity: 1
不会触发css转换,因为转换仅适用于定义良好的样式属性值。
在下一个事件循环中,浏览器将为元素定义opacity
值,因为它现在位于display: block
。
我通过记录元素在display: none
中的计算样式值并在其切换到display: block
之后立即记录了这一假设。这两个值实际上是一个定义良好的数字0
,因此这与假设不符。
PS: http://caniuse.com/#feat=requestanimationframe
截至2017年,requestAnimationFrame
的覆盖率似乎相当可接受,包括IE&gt; 9个版本。
答案 1 :(得分:2)
理论上,已经注意到浏览器将JS应用的CSS变更组合在一起。
有没有办法强制浏览器应用显示,然后是不透明度?`
是。添加以下行:
el.offsetWidth;
两个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>