我在SO上读过几个关于Bootstrap的fade
类的类似问题,但似乎都没有解决我的问题。
我知道Bootstrap 3中的淡入淡出动画是通过将.in
类添加到已经有.fade
类的元素中时在0
和1
之间切换opacity
来工作的。当处理HTML中已经存在的元素时,这对我来说很好(例如,这个JS Fiddle演示)。
问题是,当使用Javascript动态创建元素时,转换似乎不会发生。例如,以下代码将创建并显示警报,但CSS转换不会发生(在Chrome和Firefox中都进行了测试)。如果我在开发工具中手动添加和删除in
类,则淡入效果良好:
$('<div class="alert fade">This is a test</div>')
.appendTo($someElement)
.addClass('in');
很明显,.addClass()
函数正在工作,因为警报获得了in
类并被显示,但转换没有发生。你知道我该怎么做吗?
有关可编辑的演示,请参阅CodePen上的此笔。
您看到的问题是,当浏览器渲染元素时,您已经添加了"transition"类。添加一个元素不会导致它在需要渲染之前被渲染。一旦一个元素用"起始值"进行了渲染,并且还设置了转换css属性(来自"初始"类),就可以添加另一个类来触发动画。在添加其他类之前,您需要浏览器渲染初始状态,或者没有任何内容可以设置"from"的动画,并且它处于完全过渡值。
您可以尝试从width
之类的元素中读取一个值,该值应该在添加其他类之前强制重新绘制:http://codepen.io/anon/pen/hGrFe
如果你打算采用anthony的方法,我建议使用requestAnimationFrame
而不是setTimeout
,因为这是在重新绘制之后保证的(假设浏览器支持raf)。
为了避免重复,您可以在jQuery:上编写自己的repaint
方法
jQuery.fn.repaint = function() {
// getting calculated width forces repaint (hopefully?!)
this.width();
// return chain
return this;
};
// then later:
$('<div class="alert fade">This is a test</div>')
.appendTo($someElement)
.repaint()
.addClass('in');
尝试将您的javascript更改为以下内容:
var $alert = $('<div class="alert alert-success fade out">Why does this box not fade in?</div>');
$('#container').append($alert);
window.setTimeout(function () {
$alert.addClass('in');
}, 0);
以下是一些进一步的阅读,可以解释发生了什么。
http://ejohn.org/blog/how-javascript-timers-work/
为什么setTimeout(fn,0)有时很有用?