javascript 新元素上的 css 过渡

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12088819/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 15:17:56  来源:igfitidea点击:

css transitions on new elements

javascriptcssfirefoxcss-transitions

提问by Vito De Tullio

I cannot find a way to use css transitions on newly created dom elements.

我找不到在新创建的 dom 元素上使用 css 转换的方法。

let's say I have an empty html document.

假设我有一个空的 html 文档。

<body>
    <p><a href="#" onclick="return f();">click</a></p>
</body>

I also have this css

我也有这个css

#id {
    -moz-transition-property: opacity;
    -moz-transition-duration: 5s;
    opacity: 0;
}

#id.class {
    opacity: 1;
}

and this js

而这个js

function f() {
    var a = document.createElement('a');
    a.id = 'id';
    a.text = ' fading in?';
    document.getElementsByTagName('p')[0].appendChild(a);
    // at this point I expect the span element to be with opacity=0

    a.className = 'class';
    // now I expect the css transition to go and "fade in" the a        

    return false;
}

but, as you can see on http://jsfiddle.net/gwxkW/1/when you click the element appears instantaneously.

但是,正如您在http://jsfiddle.net/gwxkW/1/ 上看到的那样,当您单击该元素时,该元素会立即出现。

If I try to set the class in a timeout()i oftenfind the result, but to me it seems more a race between javascript and the css engine. Is there some specific event to listen? I tried to use document.body.addEventListener('DOMNodeInserted', ...)but it's not working.

如果我尝试在 a 中设置类,timeout()经常会发现结果,但对我而言,这似乎更像是 javascript 和 css 引擎之间的竞争。是否有一些特定的事件要收听?我尝试使用document.body.addEventListener('DOMNodeInserted', ...)但它不起作用。

How can I apply css transitions on newly created elements?

如何在新创建的元素上应用 css 过渡?

采纳答案by Jason

requestAnimationFrame()(https://developer.mozilla.org/en-US/docs/Web/API/window.requestAnimationFrame) appears to work across Firefox, Chrome and Safari. A more reliable, logical solution that setTimeout(). For older browsers (IE8), it will require a Polyfill (naturally, the transition won't occur, but the CSS will still change).

requestAnimationFrame()( https://developer.mozilla.org/en-US/docs/Web/API/window.requestAnimationFrame) 似乎适用于 Firefox、Chrome 和 Safari。一个更可靠、更合乎逻辑的解决方案,setTimeout(). 对于较旧的浏览器(IE8),它需要一个 Polyfill(自然,过渡不会发生,但 CSS 仍然会改变)。

回答by jfriend00

In Firefox, it does appear to be a race between layout completing and the CSS transition. Chrome is much more predictable. If I set the class name on a setTimeout(), Chrome always works, Firefox only works if the setTimeout()time is long.

在 Firefox 中,布局完成和 CSS 转换之间似乎是一场竞赛。Chrome 的可预测性要高得多。如果我在 a 上设置类名setTimeout(),Chrome 始终有效,Firefox 仅在setTimeout()时间很长时有效。

With this code in Firefox (even using the setTimeout()), the text shows immediately:

在 Firefox 中使用此代码(即使使用setTimeout()),文本立即显示:

function f() {
    var a = document.createElement('a');
    a.id = 'id';
    a.innerHTML = ' fading in?';
    document.getElementsByTagName('p')[0].appendChild(a);
    // at this point I expect the span element to be with opacity=0

    setTimeout(function() {
        a.className = 'fadeIn';
    }, 10);
    return false;
}

But, if I force a reflow by requesting a property that can only be returned after layout, it then starts to work in Firefox:

但是,如果我通过请求一个只能在布局后返回的属性来强制重排,它就会开始在 Firefox 中工作:

function f() {
    var a = document.createElement('a');
    a.id = 'id';
    a.innerHTML = ' fading in?';
    document.getElementsByTagName('p')[0].appendChild(a);
    // at this point I expect the span element to be with opacity=0

    // request property that requires layout to force a layout
    var x = a.clientHeight;
    setTimeout(function() {
        a.className = 'fadeIn';
    }, 10);
    return false;
}

Furthermore, once I've request that property to force a layout, I can even remove the setTimeout()and the animation works in Firefox.

此外,一旦我请求该属性强制布局,我什至可以删除setTimeout()Firefox 中的动画。

function f() {
    var a = document.createElement('a');
    a.id = 'id';
    a.innerHTML = ' fading in?';
    document.getElementsByTagName('p')[0].appendChild(a);
    // at this point I expect the span element to be with opacity=0

    // request property that requires layout to force a layout
    var x = a.clientHeight;
    a.className = 'fadeIn';
    return false;
}

You can see this last one work here in both Chrome and Firefox: http://jsfiddle.net/jfriend00/phTdt/

您可以在 Chrome 和 Firefox 中看到最后一项工作:http: //jsfiddle.net/jfriend00/phTdt/

And, here's an article that discusses the phenomenon: http://gent.ilcore.com/2011/03/how-not-to-trigger-layout-in-webkit.html

而且,这里有一篇讨论这种现象的文章:http: //gent.ilcore.com/2011/03/how-not-to-trigger-layout-in-webkit.html

回答by demian85

I found a nicer way to trigger layout and make transitions work just after appending the element to the DOM:

我找到了一种更好的方法来触发布局并在将元素附加到 DOM 后使转换工作:

window.getComputedStyle(element).opacity;