Vit*_*lio 36 javascript css firefox css-transitions
我找不到在新创建的dom元素上使用css过渡的方法.
假设我有一个空的html文档.
<body>
<p><a href="#" onclick="return f();">click</a></p>
</body>
Run Code Online (Sandbox Code Playgroud)
我也有这个CSS
#id {
-moz-transition-property: opacity;
-moz-transition-duration: 5s;
opacity: 0;
}
#id.class {
opacity: 1;
}
Run Code Online (Sandbox Code Playgroud)
而这个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;
}
Run Code Online (Sandbox Code Playgroud)
但是,正如您在http://jsfiddle.net/gwxkW/1/上看到的那样,当您单击该元素时,会立即显示.
如果我尝试在一个timeout()
i中设置类经常找到结果,但对我而言,它似乎更像是javascript和css引擎之间的竞争.是否有一些特定的事件要听?我尝试使用,document.body.addEventListener('DOMNodeInserted', ...)
但它不起作用.
如何在新创建的元素上应用css过渡?
jfr*_*d00 38
在Firefox中,它似乎是布局完成和CSS转换之间的竞争.Chrome更具可预测性.如果我在a上设置了类名setTimeout()
,Chrome总是有效,那么只有在setTimeout()
时间很长的情况下Firefox才有效.
在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;
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我通过请求只能在布局后返回的属性来强制重排,那么它将开始在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;
}
Run Code Online (Sandbox Code Playgroud)
此外,一旦我请求该属性强制布局,我甚至可以删除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;
}
Run Code Online (Sandbox Code Playgroud)
您可以在Chrome和Firefox中看到最后一个工作:http://jsfiddle.net/jfriend00/phTdt/
而且,这是一篇讨论这种现象的文章:http://gent.ilcore.com/2011/03/how-not-to-trigger-layout-in-webkit.html
dem*_*n85 15
我找到了一种更好的方法来触发布局,并在将元素附加到DOM之后使转换工作:
window.getComputedStyle(element).opacity;
Run Code Online (Sandbox Code Playgroud)
requestAnimationFrame()
(https://developer.mozilla.org/en-US/docs/Web/API/window.requestAnimationFrame)似乎适用于Firefox,Chrome和Safari.一个更可靠,更合理的解决方案setTimeout()
.对于旧版浏览器(IE8),它将需要Polyfill(当然,不会发生转换,但CSS仍会发生变化).