【问题标题】:how to delegate a "load" DOM event?如何委托“加载”DOM 事件?
【发布时间】:2013-10-12 15:11:42
【问题描述】:

我想在触发“加载”事件时调用一个函数:

events: {
    "load #eventPicture" : "_resizeHeaderPic"
}

我不想做像this.$("#eventPicture").on("load", _resizeHeaderPic); 这样的事情,因为我有很多视图(这是一个单页应用程序),我可以在加载图像之前返回显示另一个视图.所以,如果我再回到这个视图,我会有两个监听器来监听那个“加载”事件。对?通过将所有内容放入我的events hash,我可以正确地undelegate。 但似乎“加载#eventPicture”不起作用。有什么建议吗?

【问题讨论】:

    标签: backbone.js backbone-views


    【解决方案1】:

    您无法从 Backbone events 跟踪 load 事件,因为此事件仅在图像实例上触发并且不会冒泡。所以Backbone.View$el 无法追踪它。

    jQuery callback on image load (even when the image is cached)

    更新

    我建议使用另一个概念 (JSFiddle)。这是最佳做法:

    var LayoutView = Backbone.View.extend({
        el : '[data-container]',
        show : function (view) {
            // remove current view
            this.$view && this.$view.remove();
            // save link to the new view
            this.$view = view;
            // render new view and append to our element
            this.$el.html(this.$view.render().el);
        }
    });
    
    var ImageView = Backbone.View.extend({
        template : _.template('<img src="https://fbcdn-sphotos-g-a.akamaihd.net/hphotos-ak-prn2/1375054_4823566966612_1010607077_n.jpg"/>'),
        render : function () {
            this.$el.html(this.template());
            this.$('img').on('load', _.bind(this.onLoad, this));
            return this;
        },
        onLoad : function () {
            console.log('onLoad');
        }
    });
    
    var OtherView = Backbone.View.extend({
        template : _.template('lalala'),
        render : function () {
            this.$el.html(this.template());
            return this;
        }
    });
    
    var Router = Backbone.Router.extend({
        routes : {
            'other' : 'other',
            '*any' : 'image'
        },
        initialize : function (options) {
            this.layout = new LayoutView();
        },
        other : function () {
            this.layout.show(new OtherView());
        },
        image : function () {
            this.layout.show(new ImageView());
        }
    });
    
    new Router();
    Backbone.history.start();
    

    【讨论】:

    • 嗯,我明白了。我发现的唯一解决方案是覆盖视图的remove 函数并放置this.$("#muse-eventPicture").off("load");。你认为这是最简洁的解决方案吗?请记住,我已经将 remove 用于其他目的
    • 您不需要关闭load 事件。 remove 方法从 DOM 中删除整个视图元素及其所有子元素和事件。
    • 事实上,我与其他views 共享view$el 相同的div。当然,每次只显示一个视图,当一个视图被渲染时,它会取代另一个。但是“根”div 永远不会被删除。这意味着以前的侦听器可能仍在侦听事件(我遇到过重复侦听器的情况,换句话说,先前视图实例的侦听器仍在侦听 DOM 事件)。这就是为什么我需要删除我所听的内容
    • 我已经更新了一个答案并建议关注它。或者像上面描述的那样使用off
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-16
    • 1970-01-01
    • 2010-09-26
    • 1970-01-01
    相关资源
    最近更新 更多