如何在Backbone.js中插入后再次准备好DOM

1 javascript dom backbone.js

我正在使用Backbone.js开发一个应用程序.

当我切换页面时,当前页面的全局视图将替换为新页面的视图.在该视图中,我有一个典型的"渲染"功能,用新模板替换body html.

我的问题是,在更改了html之后,所以DOM,当DOM再次准备好后如何执行函数?

我必须使用它,因为我需要滚动到一个元素,并在render()不起作用后执行我的scrollTo()函数($(myElement).offset().top总是返回0).

这是我的代码:

module.exports = BaseView.extend({
    initialize: function () {
        this.render();
        $('html, body').scrollTop(this.$("#toScroll").offset().top);
    },
    template: require('./templates/home'),
    render: function () {
        this.$el.html(this.template());
        return this;
    }
});
Run Code Online (Sandbox Code Playgroud)

谢谢.

mu *_*ort 5

如果您的视图el位于DOM中并且您#toScroll位于视图中el,那么#toScroll只要您这样说就会在DOM中:

this.$el.html(this.template());
Run Code Online (Sandbox Code Playgroud)

但是,在浏览器再次获得控制权之后(即在您的视图完成所有工作之后),HTML才会呈现.el在浏览器渲染完所有内容之前,您内部的元素将没有任何大小或位置信息(当然,除非您手动定位和调整所有内容).事件的顺序如下:

  1. v = new View.
  2. initialize被叫,并打电话render.
  3. render 设置DOM中的所有内容.
  4. 视图调用this.$('#toScroll').offset()并获取零.
  5. 视图尝试scrollTop归零.
  6. 浏览器获得控制权.
  7. 浏览器呈现所有内容,此过程计算您想要的位置和偏移量.

你需要在7之后得到45.

一个简单的方法是将位置/大小依赖的东西放在_.defer回调中:

initialize: function () {
    this.render();
    var _this = this;
    _(function() {
        $('html, body').scrollTop(_this.$("#toScroll").offset().top);
    }).defer();
}
Run Code Online (Sandbox Code Playgroud)

您也可以使用setTimeout延迟为零但_.defer使您的意图更清晰.

演示:http://jsfiddle.net/ambiguous/tWSBE/