2017-11-16 3 views
0

Ich versuche, ein Array von Instanzen meiner Klasse zurückzugeben. Aber die Rückkehr kommt einfach von der window.addEventListener('load', function(){}); Funktion zurück, die ich glaube. Als wenn ich plugins in die Steuerung eintippe, ist es undefiniert.JS: Rückgabewert von EventListener Funktion

;class Parallax { 

    constructor(node) { 

     // Settings and defaults 
     // this.settings = { 
     //  container: null, 
     //  panels: [], 
     //  defaultSpeed: 0.5 
     // }; 

    } 

    static initialize() { 

     // Ensure DOM has loaded 
     window.addEventListener('load', function() { 
      // Does page contain any parallax panels? 
      let panels = document.querySelectorAll('[data-parallax]'); 
      if (panels.length > 0) { 

       let instances = []; 

       // Parallax panels found, create instances of class and return them for reference 
       for (const panel in panels) { 
        if (panels.hasOwnProperty(panel)) { 
         instances.push(new this(panels[panel])); 
        } 
       } 

       return instances; 
      } else { 
       // Page doesn't appear to have Parallax 
       return false; 
      } 
     }.bind(this)); 
    } 
} 
window.plugins = { "parallax-instances": Parallax.initialize() }; 

Nicht zu sicher, wie dies zu tun gehen, ich habe versucht, die window.addEventListener einer Variablen zugewiesen, aber das ist nicht der Wert zurückgibt. Ich behalte den Klassenbereich, indem ich this an meinen Funktionsaufruf innerhalb des Ereignishörers bindet.

Edit: Ich wollte das Plugin starten, indem Sie einfach den Code unten ist, aber nicht so sicher wie möglich, mehrere Instanzen der Klasse zurückzukehren, wie natürlich die unten läuft dabei die constructor Methode zuerst.

window.plugins = { "parallax-instances": new Parallax }; 

Edit 2 Wenn ich die Instanzen außerhalb des Eventlistener zurückkehren bekomme ich mein gewünschtes Ergebnis. Allerdings könnte dies möglicherweise instances zurückgeben, bevor die Seite richtig geladen hat?

static initialize() { 

     this.instances = []; 

     // Ensure DOM has loaded 
     window.addEventListener('load', function() { 
      // Does page contain any parallax panels? 
      let panels = document.querySelectorAll('[data-parallax]'); 
      if (panels.length > 0) { 

       // Parallax panels found, create instances of class and return them for reference 
       for (const panel in panels) { 
        if (panels.hasOwnProperty(panel)) { 
         this.instances.push(new this(panels[panel])); 
        } 
       } 
      } 
     }.bind(this)); 

     return this.instances; 
    } 

Was ich in der Konsole:

{parallax-instances: Array(2)} 
    parallax-instances:Array(2) 
     0:Parallax {} 
     1:Parallax {} 
     length:2 
    __proto__:Array(0) 
    __proto__:Object 

Antwort

1

Ihre initialize ist nichts zurück. Wenn Sie instances außerhalb Ihres Ereignis-Listeners erhöhen und das zurückgeben, können Sie die anderen return-Anweisungen entfernen. Beachten Sie, dass das zurückgegebene Array leer ist, bis der Rückruf tatsächlich aufgerufen wird (nach load).

static initialize() { 

    const instances = []; 

    window.addEventListener("load",() => { 

     const panels = document.querySelectorAll("[data-parallax]"); 
     for (let i = 0; i < panels.length; i++) 
      instances.push(new this(panels[ i ])); 

    }); 

    return instances; 

} 

Da Sie sofort ein Array Rückkehr würde, Ihre falsche Syntax würde verschwinden, und Sie würden testen .length === 0 statt. Sie können das von Ihnen angegebene Verhalten stattdessen mithilfe einer getter abrufen.

+0

Ihre obigen Code ist, was ich vorher verwendet habe, sagst du, das ist der richtige Weg? Wie konnte die 'return instances; 'möglicherweise nicht ausgeführt werden, bevor der Lade-Callback ausgeführt wird? Wie würde der Code weiterhin über den Event Listener right laufen? –

+1

Ich würde nicht sagen, dass es * der * richtige Weg ist, sondern * ein * richtiger Weg. Die 'return instances;' werden sicherlich ausgeführt, bevor der Callback ausgeführt wird. Aber das Array wird über Referenz übergeben und wird schließlich bevölkern.Das bedeutet, dass alles, was das Array verwenden möchte, auch warten sollte. Wenn Sie sicherstellen möchten, dass sie nur ein gefülltes Array erhalten, müssen Sie eine Callback- (oder Versprechens-) Syntax implementieren (d. H. Make 'initialize' akzeptiert eine Funktion, die mit einer aufgefüllten' Instanz' aufgerufen wird). – vox

3

Ein Ereignis-Listener-Funktion ein Rückruf ist, und läuft nur, wenn das Ereignis (in Ihrem Fall auf Last) geschieht.

Rückrufe können keinen Wert zurückgeben. Sie könnten eine Variable im äußeren Bereich (z. B. innerhalb Ihrer Klasse) verwenden und sie in Ihrem Ereignis-Listener neu zuweisen.

z.

constructor() { 
    this.instances = [] 
} 

Und dann (anstelle von Ihrem Event-Listener der Rücksendung):

this.instances = instances 
+0

Die Zuweisung der Instanz zum Konstruktor wird jedoch nicht wirklich helfen, da ich die Instanzen der erstellten Klasse in 'window.plugins' zurückgeben muss. Ich habe dies vorher außerhalb des eventListener gemacht, siehe aktualisierten Beitrag. –

+0

Sie könnten also einfach 'window.plugins' innerhalb Ihres Event-Listeners zuweisen, richtig? – emilyb7