在我的backbone.js应用程序中,我试图在视图元素被追加后淡出。然而,它不工作。
这里的实例:http://metropolis.pagodabox.com
var itemRender = view.render().el;
$('#items-list').append(itemRender);
$(itemRender).addClass('show');
然而,如果我添加一个小的setTimeout函数,它工作。
var itemRender = view.render().el;
$('#items-list').append(itemRender);
setTimeout(function(){
$(itemRender).addClass('show');
},10);
使用fadeIn()也可以工作,但我更喜欢使用直接的CSS进行过渡,因为它更有效,并且不喜欢使用任何setTimeout"hack"来强迫它工作。是否有一个回调可以用于append?或者有什么建议吗?完整代码如下:
itemRender: function (item) {
var view = new app.ItemView({ model: item }),
itemName = item.get('name'),
itemRender = view.render().el;
$('#items-list').append(itemRender);
$(itemRender).addClass('show');
app.itemExists(itemName);
}
CSS/少:
#items-list li {
padding: 0 10px;
margin: 0 10px 10px;
border: 1px solid @black;
.border-radius(10px);
position: relative;
.opacity(0);
.transition(opacity)
}
#items-list li.show {.opacity(1)}
你提到的这种"hack"(或它的一些变体)在web开发中偶尔是必要的,仅仅是因为浏览器呈现页面的本质。
(注意:这都是记忆,所以虽然整体想法是正确的,但请对任何细节持保留态度。)
假设你做了以下操作:
$('#someElement').css('backgroundColor', 'red');
$('#someElement').css('backgroundColor', 'blue');
你可能会看到#someElement
的背景颜色短暂地闪烁红色,然后变成蓝色,对吗?然而,这种情况不会发生,因为浏览器试图通过仅在JS执行结束时呈现最终状态来优化渲染性能。因此,红色背景甚至不会出现在页面上;你看到的只有蓝色。
与此类似,
的区别是:- <
- 设置类/gh>
:
- 等待1ms JS执行完成 <
- 设置类/gh>
是后者允许元素进入页面,并在JS执行后改变其样式,而前者只是在元素显示之前应用样式更改。
所以一般来说,window.setTimeout
应该避免,当你需要处理这些…浏览器渲染的复杂性,这真的是唯一的办法。我个人喜欢使用Underscore库的defer函数:
var itemRender = view.render().el;
$('#items-list').append(itemRender);
_(function(){
$(itemRender).addClass('show');
}).defer();
这是同样的东西,但是因为它被封装在一个库函数中,对我来说感觉不那么脏:-)(如果"后渲染"逻辑超过一两行,我可以将其纳入主干视图方法并在我的render
方法中做_(this.postRender).defer()
)。
你可以使用CSS动画
@keyframes show {
0% { opacity: 0; }
100% { opacity: 1; }
}
#items-list li {
padding: 0 10px;
margin: 0 10px 10px;
border: 1px solid @black;
.border-radius(10px);
position: relative;
}
#items-list li.show {
animation: show 1s;
}