CSS淡化无法在Chrome中使用

时间:2017-06-01 19:48:33

标签: javascript html css google-chrome

我在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来设置不透明度,因为再次显示不是原子应用),但是,这似乎是一个混乱/低效的黑客攻击。

2 个答案:

答案 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>