"Load" 事件在 "events" 属性 中,共 Backbone 视图

"Load" event in "events" property of Backbone View

通常我可以在 jQuery 中监听的任何事件我也可以在 Backbone 中监听。换句话说,如果我有:

var MyView = Backbone.View.extend();
var view = new MyView();
view.$el.html('<button>');
var onClick = function() {
    alert('woot!');
};

我想在单击按钮时触发 onClick,我 可以 做:

$('button').on('click', onClick);

但是因为我使用的是 Backbone 我会改为:

var MyView = Backbone.View.extend({
    events: {click: onClick}
});

但是,这不适用于 iframe 的 load 事件,所以如果我有:

view.$el.html('<iframe src="www.whosebug.com"></iframe>');
var onLoad = function() {
    alert('woot!');
};

我能做到:

$('iframe').on('load', onLoad);

但我做不到:

events: {load: onLoad}

我的问题分为两部分:1) 为什么这行不通,以及 2) 有没有办法解决这个问题,但仍然使用 Backbone 的 events 而不是原始 JQuery?

events are attached using delegateEvents and that uses the delegation form of jQuery's on. But on delegation only works with events that bubble中的事件:

In all browsers, the load, scroll, and error events (e.g., on an <img> element) do not bubble. [...] Such events are not supported for use with delegation, but they can be used when the event handler is directly attached to the element generating the event.

所以 events 对象中的 load 事件不会为你做任何事情,因为 load 不会冒泡 DOM 所以它不会使用事件委托。

您只能手动执行此操作(可能使用 this.$('iframe').on 将其正确隔离到视图 el 内的 iframes)或使用单独的视图 <iframe>。后者会起作用,因为如果您不在 events:

中包含选择器
events: {
    load: 'handler'
}

然后事件直接绑定到视图的 el。如果你有这样的看法:

var V = Backbone.View.extend({
    tagName: 'iframe',
    attributes: {
        src: 'http://example.com'
    },
    events: {
        load: 'loaded'
    },
    loaded: function() {
        // This should get called.
    }
});

那么 el 将是 <iframe src="http://example.com"></iframe> 并且 load 事件将直接绑定到那个 <iframe>。这可能有效也可能无效,具体取决于您需要事件处理程序执行的操作。