在 Backbone 中捕获滚动事件

Capture scroll event in Backbone

我有一个 Backbone.Marionette 项目视图。它呈现项目列表。每次有人滚动列表时,我都想听 scoll 事件。我认为这会起作用:

events: {
    'scroll ul': 'filterInteraction'
},

filterInteraction: function(){
    console.log('in filterInteraction ');
}

但是它没有捕获滚动事件。但是,当我这样做时:

onRender: function() {
     this.$el.find('ul').on( 'scroll', function(){
         console.log('scroll event captured'):  
     });
}

这将捕获滚动事件。有什么不同?两者似乎都在做同样的事情...

使用 onRender,您在每次渲染时设置事件,这是我看到的唯一区别。所以在我看来第一个解决方案会有更好的性能。

正如 anonymousday 所说,第一个选项是实施事件委托,这意味着 事件委托允许我们将单个事件侦听器附加到父元素,它将为匹配选择器的所有后代触发, 这些后代是现在存在还是将来添加。 http://learn.jquery.com/events/event-delegation/

我们有 4 个事件处理程序:

  • 滚动
    • 对于根 div : el
    • 对于 ul
  • 点击
    • 对于根 div : el
    • 对于 ul

'click' 事件冒泡所以在事件延迟中 div #root 接收它并可以处理它,但是滚动事件不冒泡所以我们不能从 #root 处理它div

在下一个示例中,我们对每个事件使用相同的代码。

如果我们点击 'ul' 我们有一个日志 click for ul 和一个日志 click for #root 因为点击事件'bubble'/爬上DOM树直到#root.
如果我们在#root 上滚动,我们有一个日志 scroll for root 因为我们直接从它捕获事件。
但是我们不能使用事件委托来处理来自 ul 的滚动,因为滚动事件不会 'bubble' / 爬上 DOM 树。

scroll on w3 site

var dbg = $('#dbg')
var log = function(val){
  dbg.append('<div>' + val + '</div>')
  .scrollTop(99999);
};
$('button').click(function(){dbg.empty() });



var i=0;
var MyView = Backbone.View.extend({
  
  events : {
    
    'click' : 'elClick' ,
    'scroll' :'elScroll' ,
    
    'click ul' : 'ulClick' ,
    'scroll ul' :'ulScroll' ,

  } ,
  elScroll : function(){ log('scroll for #root : '  + (i++)); } ,
  ulScroll : function(){ log('scroll for ul : '     + (i++)); } ,
  elClick  : function(){ log('clicked on #root :  ' + (i++)); } ,
  ulClick  : function(){ log('clicked on ul  : '    + (i++)); } ,
}); 

myView = new MyView({el : $('#root') });
#dbg{
  position: aboslute;
  border : solid 1px #EEE;
  top : 0;
  left : 0;
  right :0;
  height : 150px;
  min-height : 150px;
  overflow : auto;
  bottom : auto;
}
#dbg:hover{
    bottom : 0;
    height : auto;
}

#root{
    position: aboslute;
  border : solid 1px #EEE;
  top : 30px;
  left : 0;
  right :0;
  height : 150px;
  overflow : auto
  }
ul,li {
  border:solid 1px #CCC;
  list-style : none;
  padding : 0px;
  margin : 1px;
  cursor : pointer;
  }
ul{
  height : 200px;
  overflow : auto; 
  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://underscorejs.org/underscore-min.js"></script>
<script src="http://backbonejs.org/backbone-min.js"></script>

<div id='dbg'>debug : </div>
<div id='root'>
  <ul>
    <li>A</li>
    <li>A</li>
    <li>A</li>
    <li>A</li>
    <li>A</li>
    <li>A</li>
    <li>A</li>
    <li>A</li>
    <li>A</li>
    <li>A</li>
    <li>A</li>
    <li>A</li>
    <li>A</li>
    <li>A</li>
    <li>A</li>
    <li>A</li>
    <li>A</li>
    <li>A</li>
    <li>A</li>
    <li>A</li>
    <li>A</li>
    <li>A</li>
    <li>A</li>
    <li>A</li>
    <li>A</li>
    <li>A</li>
    <li>A</li>
    <li>A</li>
    <li>A</li>
    <li>A</li>
    <li>A</li>
    <li>A</li>
    
  </ul>
  
</div><button>clear debug</button>