JavaScript/CSS:将元素添加到 DOM 与应用其 CSS 规则之间存在延迟?

oog*_*les 5 javascript css

我正在使用 JavaScript 向 DOM 动态添加一个元素。我想在添加元素时使用 CSS3 过渡来“淡入”元素。

我正在使用类似以下的东西来实现这一点:

function add(el) {

    el.className += ' fader';
    el.style.opacity = 0;

    document.getElementById('parent-element').appendChild(el);
    //setTimeout(function () { el.style.opacity = 1; }, 5);
    el.style.opacity = 1;

}
Run Code Online (Sandbox Code Playgroud)

和 CSS:

.fader {
    -webkit-transition: opacity 0.5s;
}
Run Code Online (Sandbox Code Playgroud)

这不按预期方式工作-元素不会在掉色如果我更换就行了。el.style.opacity = 1;setTimeout(function () { el.style.opacity = 1; }, 5);,如看到注释掉上面,它按预期方式工作。

我猜第一种情况不起作用,因为在添加元素和对其应用适当的 CSS 规则之间存在一些延迟。setTimeout在第二种情况下由 产生的 5ms 延迟为应用这些规则提供了足够的时间,因此淡入淡出按预期发生。

首先,这是一个正确的假设吗?其次,有没有更好的方法来解决这个问题?该setTimout感觉就像一个黑客攻击。一旦元素应用了所有样式,是否可能会触发某些事件?

jfr*_*d00 4

为了使 CSS3 过渡起作用,对象必须以特定状态存在,然后您必须对触发过渡的对象进行更改。

由于各种原因,我在 CSS3 转换方面的所有经验都告诉我,对此有意义的状态只是当 JavaScript 返回且浏览器返回其事件循环时存在的状态。就好像,你可以告诉浏览器现在循环你的对象并记住它的状态以供将来转换的唯一方法是返回到浏览器事件循环。有一些编程原因可能会出现这种情况(因此,当您以编程方式构建对象并更改它时,它不会尝试执行转换),但这些问题可以通过不同的方式解决(例如使用特定的方法调用现在编码该对象),但它不是那样做的。

因此,您的解决方案就是我找到的方法。创建处于初始状态的对象。设置一个非常短的持续时间的计时器。从所有 javascript 返回,以便该对象将在其初始状态下进行编码,以便计时器可以触发。在计时器事件中,向触发 CSS3 转换的对象添加一个类。

老实说,我不知道 CSS3 过渡是否在规范中以这种方式指定,但我在 Safari、Firefox 和 Chrome 中的经验是它们就是这样工作的。