【问题标题】:window.onload not waiting until dom readywindow.onload 不等到 dom 准备好
【发布时间】:2015-02-27 18:35:01
【问题描述】:

尽管将 app.js 中的代码包装在 window.onload 函数中,但我一直收到错误消息

Cannot set property 'innerHTML' of undefined

由在索引路由上创建 HomeView 触发。 HomeView的render函数尝试将模板设置为render函数中el的innerHtml

this.el.innerHTML = this.template();

由于我使用的是一些 ES6,所以这段代码也使用 babeljs 进行了转换并放入一个文件(bundle.js)中。

在尝试 window.onload 函数之前,我使用 ES6 样式的 dom 准备将代码包装在 app.js 中

$(() => {

});

我如何才能真正确保 dom 已准备好,或者我应该如何将 HomeView 的 el 设置为特定的 dom 节点?

app.js

window.onload = function() {
    window.myRouter = new MyRouter();
    $(window).on("hashchange", myRouter.hashChange);     
    Backbone.history.start({pushState: true})

}

ma​​in.js

export class MyRouter extends Router {

    constructor(){
        this.routes = {
            '': 'index'
        }
        this._bindRoutes();
    }
    index(){
        this.loadView(new HomeView());
    }

主视图

export class HomeView extends View {
    constructor(){

        $("body").html(this.el);
        this.template = _.template($('#main-template').html());

        this.render();
        super();


    }

    render(){

        this.el.innerHTML = this.template();

【问题讨论】:

  • 您永远不会在您的HomeView 中设置this.el。如果它应该由View设置,那么你必须在访问this之前调用父构造函数。
  • 是的,很确定你应该在某个地方有this._super()。此外,这与是否加载 DOM 无关。 this.el 将有一个值,只要它被分配一个值并且与 DOM 的加载无关。

标签: javascript backbone.js ecmascript-6


【解决方案1】:

问题不在于onload。您只是在属性存在之前访问它。

您永远不会在 HomeView 构造函数中设置 this.el

$("body").html(this.el);
this.template = _.template($('#main-template').html());
this.render();

您正在调用this.render(),它访问this.el.innerHTML,但是您在这三行中的哪个位置设置this.el?无处可去。

如果this.el 应该由View 设置,那么您必须在访问this 之前调用父构造函数

constructor() {
    super();
    $("body").html(this.el);
    this.template = _.template($('#main-template').html());

    this.render();
}

【讨论】:

    【解决方案2】:

    使用

    $(document).ready
    

    而不是

    window.onload
    

    【讨论】:

    • 请解释为什么这样可以解决问题。 window.onload 的调用时间甚至晚于 $(document).ready,所以我不明白为什么切换会有所帮助。