2016-11-04 3 views
0

Ich schrieb einige JavaScript für ein Menü toggle, jetzt möchte ich diese für mehrere Elemente wiederverwenden und ich kämpfe auf, wie ich eine Schließung erstellen kann, um dies richtig zu machen.Probleme mit JavaScript Closures haben

Jetzt ist die Wirkung nur auf dem letzten registrierten Element, becaus des Umfangs der Setup-Optionen usw.

var selectGroup = (function() { 
 

 
    var defaults = { 
 
     element: document.getElementById('form-select'), 
 
    }; 
 

 
    var setup = { 
 
     open: false 
 
    }; 
 
    var opt = {}; 
 

 
    self.init = function (options) { 
 
     opt = options || defaults; 
 
     opt.element = options.element || defaults.element; 
 
     setup.navButton = opt.element.getElementsByClassName('nav-button')[0]; 
 
     setup.ulTag = opt.element.getElementsByTagName('ul')[0]; 
 
     setup.buttonArrow = opt.element.getElementsByTagName('span')[1]; 
 
     registerEvents(); 
 
    }; 
 

 

 
    registerEvents = function() { 
 
     opt.element.onclick = function() { 
 
      if (setup.open) { 
 
       setup.buttonArrow.setAttribute('class', 'expand-arrow'); 
 
       setup.ulTag.setAttribute("style", 'max-height:0;'); 
 
      } else { 
 
       setup.buttonArrow.setAttribute('class', 'contract-arrow'); 
 
       setup.ulTag.setAttribute("style", 'max-height:600px;'); 
 
      } 
 
      /*Toggle*/ 
 
      setup.open = !setup.open; 
 
     } 
 
    }; 
 

 
    return self; 
 
})(); 
 

 
selectGroup.init({element: document.getElementById('person-nav')}); 
 
selectGroup.init({element: document.getElementById('situation-nav')}); 
 
selectGroup.init({element: document.getElementById('region-nav')});

Antwort

0

Es ist kein Verschluss Ausgabe, können Sie immer Ihre opt.element überschrieben mit das neueste Element, deshalb nur mit dem letzten funktioniert.

Sie sollten die Daten in opts durch eine eindeutige ID speichern. Hier

ist ein funktionierendes Beispiel mit super einfach Markup (hässlich): https://jsfiddle.net/cone0oof/2/

0

Die Lösung dafür ist, den Verschluss zu entfernen, verwenden Sie die lokalen scoped Variablen und geben sie als Parameter statt, weil Sie sie sein wollen für jedes andere Element neu erstellt.

Hier unten ist fast das gleiche wie Ihr ursprünglicher Code. Ich habe meine Änderungen mit Inline-Kommentaren markiert.

var selectGroup = (function() { 

    var defaults = { 
     element: document.getElementById('form-select'), 
    }; 

    self.init = function (options) { 
     var setup = { //make it local inside init() 
      open: false 
     }; 
     var opt = {}; //make it local inside init() 

     opt = options || defaults; 
     opt.element = options.element || defaults.element; 
     setup.navButton = opt.element.getElementsByClassName('nav-button')[0]; 
     setup.ulTag = opt.element.getElementsByTagName('ul')[0]; 
     setup.buttonArrow = opt.element.getElementsByTagName('span')[1]; 
     registerEvents(opt, setup); //pass them as parameters 
    }; 


    registerEvents = function (opt, setup) { //receive the parameters 
     opt.element.onclick = function() { 
      if (setup.open) { 
       setup.buttonArrow.setAttribute('class', 'expand-arrow'); 
       setup.ulTag.setAttribute("style", 'max-height:0;'); 
      } else { 
       setup.buttonArrow.setAttribute('class', 'contract-arrow'); 
       setup.ulTag.setAttribute("style", 'max-height:600px;'); 
      } 
      /*Toggle*/ 
      setup.open = !setup.open; 
     } 
    }; 

    return self; 
})(); 

selectGroup.init({element: document.getElementById('person-nav')}); 
selectGroup.init({element: document.getElementById('situation-nav')}); 
selectGroup.init({element: document.getElementById('region-nav')});