Javascript Backbone.js 检测滚动事件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7634529/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 02:59:24  来源:igfitidea点击:

Backbone.js detecting scroll event

javascriptbackbone.js

提问by ericbae

I have a following view

我有以下观点

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

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

  detect_scroll: function() {
    console.log('detected');
  }
});

and I initialize it via

我通过

var full_window = new FullWindow({el:$('body')});

But I don't think it's working.

但我不认为它有效。

When I change the events to

当我将事件更改为

events : {
  "click" : "detect_scroll"
},

It's fine.

没关系。

What's wrong?

怎么了?

回答by nrabinowitz

I don't think that the bodyelement will fire a scroll event unless you explicitly give it a scrollbar by setting set its overflowproperty to scrollin CSS. From the jQuery docs:

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

The scroll event is sent to an element when the user scrolls to a different place in the element. It applies to window objects, but also to scrollable frames and elements with the overflow CSS property set to scroll (or auto when the element's explicit height or width is less than the height or width of its contents).

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

Assuming that you aren't explicitly giving the bodyelement a scrollbar with overflow:scrolland/or a fixed height, the scrollevent you want to listen for is probably being fired by the windowobject, not the body.

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

I think the best approach here is to drop the Backbone event binding (which is really just a shorthand, and only works on events within the view.elelement) and bind directly to the window in initialize():

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

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

回答by qbolec

I think the problem is that Backbone uses event delegation to capture events, that is it attaches listeners to the this.$el, and that the scrollevent does not bubble up by definition. So, if the scrollevent occurs for a child (or descendant) of this.$el, then this event can not be observed at this.$el.

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

The reason it works for click, is just because clickbubbles up.

它适用的原因click,只是因为click冒泡。

回答by Kyle Rogers

The scroll bars for body and window are different and you have to make sure you aren't scrolling on the window object. Here is a jsfiddle that illustrates the issue you are probably encountering.

body 和 window 的滚动条是不同的,你必须确保你没有在 window 对象上滚动。这是一个 jsfiddle,它说明了您可能遇到的问题。

jsfiddle

提琴手

I'm not for sure if you can change the 'el' to the document.window object, but I don't think that would be a good solution anyway. I would say your best bet is to either use CSS like I've done to help you with the body element or to create a div inside the body and reference that verse the body tag.

我不确定您是否可以将“el”更改为 document.window 对象,但我认为这无论如何都不是一个好的解决方案。我会说你最好的选择是要么像我一样使用 CSS 来帮助你处理 body 元素,要么在 body 内创建一个 div 并引用该 verse 标签。

Good luck.

祝你好运。

回答by smishra

I had same issue and this is how I implemented it

我有同样的问题,这就是我实现它的方式

var MyView = Backbone.View.extend({
el: $('body'),
initialize: function() {
    $(window).scroll(function() {
        if ($(window).scrollTop()!=0 && $(window).scrollTop() == $(document).height() - $(window).height()) {
            if (mpListModel.get('next')) {
                var res = confirm('Next page?');
                if (res==true) {
                    myView.fetch()
                }
            }
        }
    });
},
events: {},
fetch: function() {
    //fetch stuff
}

}); var myView = MyView();

}); var myView = MyView();