2016-07-20 4 views
0

Ich habe den folgenden JavaScript-Code:ändert Verweis auf bestehendes Ereignisse

var MyGlobalRef = (function() { 

    function init(obj1, obj2) { 

     prepareEvents(obj1); 
     prepareEvents(obj2); 

     function prepareEvents(obj) { 

      var handleMouseUp = function (evt) { 
       // do work with obj 
      }; 

      obj.addEventListener('mouseup', handleMouseUp); 
     } 
    } 
    return { 
     init: init 
    } 
})(); 

In meiner Haupt-Seite, ich bin die init Funktion wie diese häufig Aufruf:

function moveNext(){ 
    MyGlobalRef.init(getNewObj1(), getNewObj2()); 
} 

Mein Problem ist, dass auf die Funktion moveNext() tendiere ich dazu, die vorhandenen Objekte zu ersetzen, was bedeutet, dass es immer nur 2 Objekte auf der Seite gibt. Je mehr ich jedoch moveNext rufe, desto mehr Event-Listener werden generiert. Also, wenn ich 3 mal moveNext 3 Mal, das Mouse-up-Ereignis dreimal pro Maus feuert. Die offensichtliche Lösung besteht darin, nur das erste Mal addEventListener anzurufen. Das Problem dabei ist jedoch, dass obj (das im Mouse-up-Ereignis verwendet wird) nicht aktualisiert wird und immer noch auf das Original obj verweist. Außerdem habe ich removeEventListener nicht verwendet, weil ich keinen Verweis auf obj habe, sobald es initiiert wird.

+0

Lassen Sie Ihre 'init' -Funktion' destroy' anstelle von 'undefined' zurückgeben. Wenn Sie 'init' aufrufen, bekommen Sie eine Funktion' destroy' zurück, die Sie aufrufen können, um 'removeEventListener' für Ihre' obj1' und 'obj2' auszuführen. Damit Sie die gespeicherte 'destroy'-Funktion aufrufen können, bevor Sie' MyGlobalRef.init' anrufen. – anvk

Antwort

2

Um auf meinen Kommentar zu erweitern. Hier ist, was ich mir vorstelle. Sie gelangen wieder eine destroy Funktion als Folge der init Ausführung

Lösung # 1

var MyGlobalRef = (function() { 

    function init(obj1, obj2) { 

     prepareEvents(obj1); 
     prepareEvents(obj2); 

     function prepareEvents(obj) { 

      var handleMouseUp = function (evt) { 
       // do work with obj 
      }; 

      obj.addEventListener('mouseup', handleMouseUp); 
     } 

     return function() { 
      obj1.removeEventListener('mouseup'); 
      obj2.removeEventListener('mouseup'); 
     }; 
    } 
    return { 
     init: init 
    } 
})(); 


// cleanup is a variable stored in your code to run a cleanup on obj1 and obj2 later on 

function moveNext(){ 
    if (cleanup) { 
     cleanup(); 
    } 

    cleanup = MyGlobalRef.init(GetNewObj1A(), GetNewObj1A()); 
} 

Lösung # 2 Bezug auf obj1 und obj2 in Verschluss halten.

var MyGlobalRef = (function() { 

    var _obj1; 
    var _obj2; 

    function init(obj1, obj2) { 

     prepareEvents(obj1); 
     prepareEvents(obj2); 

     function prepareEvents(obj) { 

      var handleMouseUp = function (evt) { 
       // do work with obj 
      }; 

      obj.addEventListener('mouseup', handleMouseUp); 
     } 

     _obj1 = obj1; 
     _obj2 = obj2; 
    } 
    function cleanup() { 
     if (_obj1) { 
      _obj1.removeEventListener('mouseup'); 
     } 

     if (_obj2) { 
      _obj2.removeEventListener('mouseup'); 
     } 
    } 
    return { 
     init: init, 
     cleanup: cleanup 
    } 
})(); 



function moveNext(){ 
    MyGlobalRef.cleanup(); 
    MyGlobalRef.init(GetNewObj1A(), GetNewObj1A()); 
} 
+0

Ich mag Lösung 2. Aber das Problem ist, dass 'removeEventListener' die Übergabe der angefügten Funktion erfordert. Daher muss ich den Umfang von 'handleMouseUp' erweitern. Dadurch würde ich jedoch den Zugriff auf "obj" verlieren, der innerhalb des Handlers verwendet wird. Obwohl Lösung 2 sauber aussieht, funktioniert es nicht. Ich denke, das gleiche Konzept gilt für Lösung 1 – yazanpro

+0

@yazanpro Sie können das angeklickte Objekt von 'evt' erhalten und Sie können' handleMouseUp' außerhalb von 'prepareEvents' verschieben, damit Sie einen Verweis auf die Methode für' removeEventListener' haben - Hoffentlich macht das Sinn. – Jamiec

+0

Ich denke du hast Recht. Nun, da dies eine sehr vereinfachte Version meines eigentlichen Codes ist, denke ich, dass ich ziemlich viel Arbeit vor mir habe. – yazanpro

-1

Sie rufen prepareEvents vor der Funktion auf, setzen Sie die Funktion prepareEvents (obj) vor Ihrer init-Funktion. Versuch es.