【问题标题】:Backbone.js detecting scroll eventBackbone.js 检测滚动事件
【发布时间】:2011-10-03 11:45:26
【问题描述】:

我有以下看法

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

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

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

我通过

初始化它
var full_window = new FullWindow({el:$('body')});

但我认为它不起作用。

当我将事件更改为

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

没关系。

怎么了?

【问题讨论】:

    标签: javascript backbone.js


    【解决方案1】:

    我认为 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);
    }
    

    【讨论】:

    • body 确实收到了滚动事件。请在我的回答中参考 jsfiddle。起初我也想知道同样的事情,但在使用 CSS 操作之后,我终于得到了 body 元素的滚动条。
    • 通过像上面那样绕过主干事件哈希,当您滚动时,您将失去对“this”的引用。它将不再是 FullWindow 对象。它将是窗口对象。
    • @KyleRogers - 对this 的引用将受_.bindAll 函数的约束 - 这就是该行的重点。见documentcloud.github.com/underscore/#bindAll
    • Backbone 的默认事件绑定发生在调用 initialize() 之前。因此,当我需要手动绑定事件时,我会在 initialize() 中进行。但是没有正确的方法来做到这一点 - 这取决于你。
    • @AntonEgorov - $(window).off(this.detect_scroll) 应该这样做。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      jsfiddle

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

      祝你好运。

      【讨论】:

        【解决方案4】:

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

        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();

        【讨论】:

        • 这种方法的问题是滚动事件永远不会被清除/取消注册,这意味着在每次软重新加载时 - 或者每当通过主干路由器重新访问页面时 - 滚动事件都会重新 -已注册。
        【解决方案5】:
        afterRender: function() {
            // <div id="page-content" class="page-content"> la class qui contiens le scroll
            var $scrollable = this.$el.find('.page-content'); 
            $scrollable.scroll(function() {
                   alert("event scroll ");
            });
        },
        

        【讨论】:

        • 请不要只发布代码作为答案,还要解释您的代码的作用以及它如何解决问题的问题。带有解释的答案通常更有帮助,质量更高,更有可能吸引投票。
        猜你喜欢
        • 1970-01-01
        • 2018-04-05
        • 1970-01-01
        • 1970-01-01
        • 2019-09-02
        • 1970-01-01
        • 1970-01-01
        • 2021-08-21
        • 2021-05-24
        相关资源
        最近更新 更多