我正在使用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;
}
});
感谢。
答案 0 :(得分:5)
如果您的视图el
位于DOM中,并且您的#toScroll
位于视图的el
内,那么只要您这样说,#toScroll
就会出现在DOM中:
this.$el.html(this.template());
但是,在浏览器再次获得控制权之后(即在您的视图完成所有工作之后),HTML才会呈现。 el
内的元素在浏览器渲染完所有内容之前不会有任何大小或位置信息(当然,除非您手动定位和调整所有内容)。事件的顺序如下:
v = new View
。initialize
被调用,并调用render
。render
设置DOM中的所有内容。this.$('#toScroll').offset()
并获取零。scrollTop
为零。您只需要在 7 之后获得 4 和 5 。
一种简单的方法是将您的位置/尺寸依赖的内容放在_.defer
回调中:
initialize: function () {
this.render();
var _this = this;
_(function() {
$('html, body').scrollTop(_this.$("#toScroll").offset().top);
}).defer();
}
您也可以使用延迟为零的setTimeout
,但_.defer
会让您的意图更加清晰。