css在新元素上的转换

css transitions on new elements

本文关键字:转换 元素 新元素 css      更新时间:2023-09-26

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

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

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

我也有这个css

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

这个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;
}

但是,正如你在http://jsfiddle.net/gwxkW/1/单击时,元素会立即出现。

如果我尝试在timeout()中设置类,我经常会发现结果,但对我来说,这似乎更像是javascript和css引擎之间的竞争。有什么具体的事件要听吗?我尝试使用document.body.addEventListener('DOMNodeInserted', ...),但它不起作用。

如何在新创建的元素上应用css转换?

在Firefox中,布局完成和CSS转换之间确实存在竞争。Chrome的可预测性要高得多。如果我在setTimeout()上设置类名,Chrome总是有效的,Firefox只有在setTimeout()时间长的情况下才有效。

在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;
}

但是,如果我通过请求一个只能在布局后返回的属性来强制回流,那么它就会在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;
}

此外,一旦我请求该属性强制布局,我甚至可以删除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;
}

你可以在Chrome和Firefox中看到最后一个作品:http://jsfiddle.net/jfriend00/phTdt/

下面是一篇讨论这一现象的文章:http://gent.ilcore.com/2011/03/how-not-to-trigger-layout-in-webkit.html

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

window.getComputedStyle(element).opacity;

requestAnimationFrame()(https://developer.mozilla.org/en-US/docs/Web/API/window.requestAnimationFrame)似乎适用于Firefox、Chrome和Safari。一个比setTimeout()。对于较旧的浏览器(IE8),它将需要一个Polyfill(当然,转换不会发生,但CSS仍然会改变)。