web-dev-qa-db-de.com

Backbone.js erkennt ein Scroll-Ereignis

Ich habe folgende Ansicht

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

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

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

und ich initialisiere es über

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

Aber ich glaube nicht, dass es funktioniert.

Wenn ich die Ereignisse auf ändere

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

Das ist gut.

Was ist falsch?

21
ericbae

Ich glaube nicht, dass das Element body ein Bildlaufereignis auslöst, es sei denn, Sie geben ihm explizit eine Bildlaufleiste, indem Sie die Eigenschaft overflow in CSS auf scroll setzen. Aus den jQuery-Dokumenten:

Das Bildlaufereignis wird an ein Element gesendet, wenn der Benutzer an eine andere Stelle im Element scrollt. Dies gilt für Fensterobjekte, aber auch für scrollbare Frames und Elemente, bei denen die Überlauf-CSS-Eigenschaft auf scroll gesetzt ist (oder auto, wenn die explizite Höhe oder Breite des Elements geringer als die Höhe oder Breite des Inhalts ist).

Wenn Sie dem body-Element nicht explizit eine Bildlaufleiste mit overflow:scroll und/oder einer festen Höhe zuweisen, wird das scroll-Ereignis, das Sie überwachen möchten, wahrscheinlich vom window-Objekt ausgelöst, nicht von der body.

Ich denke, der beste Ansatz hier ist, die Backbone-Ereignisbindung zu löschen (was wirklich nur eine Abkürzung ist und nur für Ereignisse innerhalb des view.el-Elements funktioniert) und direkt an das Fenster in initialize() zu binden:

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

Ich denke, das Problem ist, dass Backbone Ereignisdelegation verwendet, um Ereignisse zu erfassen, das heißt, es hängt Listener an den this.$el an und das scroll-Ereignis wird nicht per Definition ausgelöst. Wenn also das scroll-Ereignis für ein Kind auftritt (oder Nachkommen) von this.$el, dann kann dieses Ereignis bei this.$el nicht beobachtet werden.

Der Grund, warum es für click funktioniert, liegt einfach daran, dass click sprudelt.

11
qbolec

Die Bildlaufleisten für Hauptteil und Fenster sind unterschiedlich, und Sie müssen sicherstellen, dass Sie nicht für das Fensterobjekt einen Bildlauf durchführen. Hier ist ein jsfiddle, das das Problem veranschaulicht, dem Sie wahrscheinlich begegnen. 

jsfiddle

Ich bin mir nicht sicher, ob Sie das 'el' in das document.window-Objekt ändern können, aber ich glaube nicht, dass dies ohnehin eine gute Lösung wäre. Ich würde sagen, dass Sie am besten CSS verwenden, wie ich es getan habe, um Ihnen beim body-Element zu helfen, oder ein div innerhalb des body zu erstellen und diesen Vers auf das body-Tag zu verweisen. 

Viel Glück.

2
Kyle Rogers

Ich hatte dasselbe Problem und so habe ich es umgesetzt

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

0
smishra