Onkel Schnitzel: Verständnisproblem mit JS-Objekten, Eigenschaften und Methoden

Hallo,

ich benutze auf meiner Website eine JavaScript-Funktion, die mir das Navigationsmenü ab einer bestimmten Scrollposition fixiert. Ich rufe die Funktion per window.onscroll auf:

<script>
  window.onscroll = function() { NavMenue.fix(); };
</script>

Das funktioniert soweit auch. Das hier ist die Funktion dazu. Wieso ich das so gebaut habe, versuche ich gleich zu erklären...

  
var NavMenue = {  
	  
  pos : window.pageYOffset,  
  
  fix : function() {  
    var pos = window.pageYOffset;  
    this.pos = pos;  
    //console.log(this.pos);  
  
    /* Fixieren */  
  }  
	  
};  

Ich brauche nämlich die zuletzt ermittelte Scrollposition auf einer Unterseite noch für eine andere Funktion. Deshalb dachte ich, ich könnte im Objekt 'NavMenue' die letzte Scrollposition als Eigenschaft 'pos' speichern und an anderer Stelle wiederverwenden. Im Dokument gibt es also zwei script-Blöcke, in denen einmal mit der fix-Methode das Menü fixiert und dann die Scrollposition in der pos-Eigenschaft gespeichert wird und dann dieser Wert abgefragt werden soll.

  
  

<!--html-->
<script>
  window.onscroll = function() { NavMenue.fix(); };
</script>
<!-- HTML-- >
<script>
  window.onscroll = function() { console.log(NavMenue.pos); };
</script>
<!--HTML-->

Leider funktioniert das nicht so wie erhofft. Ich bekomme immer nur den pos-Wert zurück, mit dem das Objekt angelegt wurde, nicht die Veränderungen nach .fix().

Irgendwo schein ich ja nen schweren Denkfehler zu haben, aber ich komme nicht drauf.

Beste Grüße

Onkel Schnitzel

  1. Hallo,

    window.onscroll = function() { NavMenue.fix(); };

    window.onscroll = function() { console.log(NavMenue.pos); };

      
    Das ist das sogenannte [traditionelle Event-Handling](http://molily.de/js/event-handling-grundlagen.html#traditionelles-event-handling), das gibt es seit Netscape 2.0. Man registriert einen Event-Handler, indem man einer speziellen Objekteigenschaft (meist on{eventname} benannt) einen Wert zuweist. Dieser Wert ist ein Funktionsobjekt.  
      
    Diese Eigenschafts-Zuweisung verhält sich wieder jede andere auch: Setzt man einen Wert, wird der alte überschrieben. Analogie:  
      
    ~~~javascript
    window.foo = 1;  
    window.foo = 2;  
    alert(window.foo); // ergibt 2, nicht 1 und schon gar nicht 3 ;)
    

    Wenn du window.onscroll setzt, so kannst du immer nur *eine* Handlerfunktion setzen.

    window.onscroll = function() { NavMenue.fix(); };

    Hiermit setzt du den Handler.

    window.onscroll = function() { console.log(NavMenue.pos); };

    Und hiermit überschreibst du ihn mit einer neuen Funktion. Es wird nur die zuletzt gesetzte Funktion function() { console.log(NavMenue.pos); } aufgerufen, nicht die erste.

    Das ist ein bekannter Nachteil des traditionellen Event-Handlings.

    Entweder du baust beides in eine Funktion ein:

    window.onscroll = function() {  
      NavMenue.fix();  
      console.log(NavMenue.pos);  
    };
    

    Oder du verwendest das moderne, W3C-konforme Event-Handling.

    window.addEventListener('scroll', function() { … Handler 1}, false);  
    window.addEventListener('scroll', function() { … Handler 2}, false);  
    window.addEventListener('scroll', function() { … Handler 3}, false);  
    // ad inifinitum
    

    Irgendwo schein ich ja nen schweren Denkfehler zu haben, aber ich komme nicht drauf.

    Du hättest deine Debug-Ausgabe aktivieren können:

    //console.log(this.pos);

    Dann wäre dir aufgefallen, dass NavMenue.fix gar nicht aufgerufen wird. :)

    Mathias

    1. Hallo molily,

      Und hiermit überschreibst du ihn mit einer neuen Funktion. Es wird nur die zuletzt gesetzte Funktion function() { console.log(NavMenue.pos); } aufgerufen, nicht die erste.

      Das hatte ich sogar kurzzeitig im Verdacht, bin aber wieder davon abgekommen.

      Das ist ein bekannter Nachteil des traditionellen Event-Handlings.

      Umso peinlicher, da ich vorher auf deiner Seite war und mein Objekt nach deinem Beispiel aufgebaut habe. Ich lese oft bloß das, was ich gerade brauche, deshalb fehlen mir manchmal Grundlagen. Ich bin leider überhaupt kein Theoretiker. Aber deine Seite ist super!

      Oder du verwendest das moderne, W3C-konforme Event-Handling.

      Das funktioniert jetzt. Danke ;-)

      Onkel Schnitzel