Backbone.js检测滚动事件

eri*_*bae 21 javascript backbone.js

我有以下观点

var FullWindow = Backbone.View.extend({
  initialize: function() {
    _.bindAll(this, 'detect_scroll');
  },

  // bind the events
  events : {
    "scroll" : "detect_scroll"
  },

  detect_scroll: function() {
    console.log('detected');
  }
});
Run Code Online (Sandbox Code Playgroud)

我通过它初始化它

var full_window = new FullWindow({el:$('body')});
Run Code Online (Sandbox Code Playgroud)

但我不认为它有效.

当我将事件更改为

events : {
  "click" : "detect_scroll"
},
Run Code Online (Sandbox Code Playgroud)

没关系.

怎么了?

nra*_*itz 30

我不认为该body元素将触发滚动事件,除非您通过在CSS 中将其overflow属性设置为显式为其提供滚动条scroll.来自jQuery文档:

当用户滚动到元素中的不同位置时,滚动事件被发送到元素.它适用于窗口对象,也适用于可滚动框架和元素,其中溢出CSS属性设置为滚动(或当元素的显式高度或宽度小于其内容的高度或宽度时自动).

假设您没有明确地为body元素提供具有overflow:scroll和/或固定高度的滚动条,scroll您想要侦听的事件可能是由window对象触发的,而不是body.

我认为这里最好的方法是删除Backbone事件绑定(这实际上只是一个简写,只适用于view.el元素中的事件)并直接绑定到窗口initialize():

initialize: function() {
    _.bindAll(this, 'detect_scroll');
    // bind to window
    $(window).scroll(this.detect_scroll);
}
Run Code Online (Sandbox Code Playgroud)

  • @KyleRogers - 对`this`的引用将受到`_.bindAll`函数的约束 - 这就是该行的重点.请参阅http://documentcloud.github.com/underscore/#bindAll (2认同)
  • Backbone的默认事件绑定恰好在调用initialize()之前发生.因此,当我需要手动绑定事件时,我会在initialize()中执行此操作.但是没有正确的方法 - 这取决于你. (2认同)
  • @AntonEgorov - `$(window).off(this.detect_scroll)`应该这样做. (2认同)

qbo*_*lec 11

我认为问题在于Backbone使用事件委托来捕获事件,即它将侦听器附加到this.$el,并且scroll事件不会按定义冒泡.因此,如果scroll事件发生在子项(或后代)中this.$el,则无法在此处观察到此事件this.$el.

它起作用的原因click,只是因为click起泡.