3

在我的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 “hacks”来强制它工作。有没有可以用于追加的回调?或者有什么建议?完整代码如下:

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)}
4

2 回答 2

9

您提到的这种“黑客”(或它的某些变体)有时对于 Web 开发是必要的,这仅仅是由于浏览器呈现页面的方式的性质。

(注意:这全凭记忆,所以虽然总体思路是正确的,但请谨慎对待任何细节。)

假设您执行以下操作:

$('#someElement').css('backgroundColor', 'red');
$('#someElement').css('backgroundColor', 'blue');

您可能希望看到背景颜色#someElement闪烁红色一会儿,然后变成蓝色,对吗?但是,这不会发生,因为浏览器试图通过仅在 JS 执行结束时渲染最终状态来优化渲染性能。结果,红色背景甚至永远不会出现在页面上;你所看到的只是蓝色。

同样,这里的区别是:

  1. 附加
  2. 设置类

和:

  1. 附加
  2. 等待 1ms 让 JS 执行完成
  3. 设置类

是后者允许元素进入页面并且在执行 JS 之后有其样式更改,而前者只是在元素显示之前应用样式更改。

因此,虽然通常window.setTimeout应该避免,但当您需要处理这些......浏览器渲染的复杂性时,它确实是唯一的方法。我个人喜欢使用 Underscore 库的 defer 函数:

var itemRender = view.render().el;

$('#items-list').append(itemRender);

_(function(){
    $(itemRender).addClass('show'); 
}).defer();

这是同样糟糕的事情,但是因为它被封装在一个库函数中,所以对我来说感觉不那么脏:-)(如果“后渲染”逻辑超过一两行,我可以将它考虑到 Backbone View 方法中并_(this.postRender).defer()在我的render方法中执行)。

于 2013-04-27T20:07:49.287 回答
2

您可以使用 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;
}
于 2013-04-27T20:27:49.427 回答