2016-04-06 14 views
1

Ich bin auf den Event-Handler-Aspekt von Javascript fest.Javascript: Binden einer benutzerdefinierten Objektmethode an einen Ereignis-Listener

rowCells [j] ist eine Referenz auf ein eindeutiges Objekt. galleryCell ist auch eine Referenz auf neu erstellte Objekte. Es liegt nahe, dass die beiden sich verbinden könnten.

Es scheint jedoch, dass die beiden Referenzen überhaupt nicht miteinander verbunden sind, damit der Ereignis-Listener ordnungsgemäß funktioniert. Alle Zellen werden demselben Objekt zugewiesen (dem letzten galleryCell-Objekt).

Die Variable galleryCell befindet sich in einer for-Schleife, die bei jeder Iteration eine neue Referenz erhält. Warum sind diese Referenzen verloren?

function TypeGallery (galleryObj) 
{ //receives the <div> element that contains rows and cells of a gallery 

    //Properties -------------- 
    var galleryCellArr = []; //array of galleryZoomCell objects 

    //Methods ----------------- 
    var Initialize = function() 
    { 
     var rows  = galleryObj.children; 
     var rowCount = rows.length; 
     for (var i=0;i<rowCount;i++) 
     { 
     var rowCells  = rows[i].children; 
     var rowCellCount = rowCells.length; 
     for (var j=0;j<rowCellCount;j++) 
     { 
      var sliderObj = new TypeSlider(300,1,false); 
      var galleryCell = new TypeGalleryZoomCell(rowCells[j],sliderObj) 
      galleryCellArr.push(galleryCell); 

      rowCells[j].onmousedown = function() {galleryCell.Deploy();}; 
      rowCells[j].onmouseup = function() {galleryCell.Retract();}; 
     } 
     } 
    } 

    //Initialization 
    Initialize(); 
} 
+1

Die Variable galleryCell ist nicht auf den for-Block beschränkt, sondern auf die gesamte Initialize-Funktion. Es wird daher bei jeder Iteration komplett neu geschrieben, und wenn das Ereignis ausgelöst wird, ist die aufgerufene Funktion nur die letzte Zuweisung für galleryCell. Werfen Sie einen Blick auf http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example – TAGraves

Antwort

2

versuchen, wie dies eine Javascript-Schließung innerhalb einer for-Schleife zu setzen:

function TypeGallery (galleryObj) 
{ //receives the <div> element that contains rows and cells of a gallery 

    //Properties -------------- 
    var galleryCellArr = []; //array of galleryZoomCell objects 

    //Methods ----------------- 
    var Initialize = function() 
    { 
     var rows  = galleryObj.children; 
     var rowCount = rows.length; 
     for (var i=0;i<rowCount;i++) 
     { 
     var rowCells  = rows[i].children; 
     var rowCellCount = rowCells.length; 
     for (var j=0;j<rowCellCount;j++) 
     { 
      (function(j) { 

       var sliderObj = new TypeSlider(300,1,false); 
       var galleryCell = new TypeGalleryZoomCell(rowCells[j],sliderObj) 
       galleryCellArr.push(galleryCell); 

       rowCells[j].onmousedown = function() {galleryCell.Deploy();}; 
       rowCells[j].onmouseup = function() {galleryCell.Retract();}; 

      })(j); 
     } 
     } 
    } 

    //Initialization 
    Initialize(); 
} 
+0

Ja, obwohl beachten Sie, dass es wahrscheinlich besser ist, eine einzelne Funktion außerhalb der Schleife zu erstellen und dann rufe es innerhalb der Schleife auf, anstatt bei jeder Iteration eine neue anonyme Funktion zu machen. – TAGraves

+0

Wow, ja, das funktioniert. Danke für die Antwort ! Jetzt muss ich herausfinden, warum ich diesen blinden Fleck in meinem Verständnis von Javascript Scoping habe. –

0

ok, ich verstehe jetzt die Probleme mit Javascript und Block-scope Einschränkung.

Auf dem Weg ich eine zweite mögliche Lösung entdeckt:
Gibt es Einwände oder Vorbehalte in Ersetzen des ‚var‘ mit ‚lassen‘ innen für Schleifen?
Dieser Code funktioniert gut, soweit ich das beurteilen kann. Irgendwelche versteckten Gefahren?

var Initialize = function() 
    { 
     var rowsArr = galleryObj.children; 
     var rowCount = rowsArr.length; 
     for (let i=0;i<rowCount;i++) 
     { //Javascript does not understand block-scope unless the let keyword 
     let rowCellsArr = rowsArr[i].children; 
     let rowCellCount = rowCellsArr.length; 
     for (let j=0;j<rowCellCount;j++) 
     { 
      //Attach (rowCellsArr[j]); 

      let sliderObj = new TypeSlider(300,1,false); 
      let galleryCell = new TypeGalleryZoomCell(rowCellsArr[j],sliderObj); 
      galleryCellArr.push(galleryCell); 

      galleryCellArr[galleryCellArr.length-1].cell.onmousedown = function() {galleryCell.Deploy();}; 
      galleryCellArr[galleryCellArr.length-1].cell.onmouseup = function() {galleryCell.Retract();}; 

     } 
     } 
    } 
Verwandte Themen