2012-04-01 16 views
0

Ich erstelle dieses Mini-Modul-Framework und versuche eine Moduldefinition in einem dynamisch geladenen HTML wiederzuverwenden. Es ist, als würde man das gleiche Wetter-Widget-Skript verwenden, um zwei oder mehr Wetter-Widgets auf dem Bildschirm zu steuern, eines, das beim Laden der Seite geladen wird, und die anderen, die später geladen werden. Das Definieren des Moduls verwendet dieses Format.Skript nur für neu hinzugefügten HTML ausführen

framework.module.create('module_name',function(){ 

    //execute when starting the module 
    this.init = function(){ 

     //for example, bind a click handler 
     $('button').on('click',function(){ 
      alert('foo'); 
     }); 
    } 
}); 

der Modulname und Konstruktor wird in einem Array und während der Seitenlast, wie

ausgeführt gespeicherten
//store 
function create(name,fn){ 
    modules[name] = fn; 
} 

//execute 
function start(){ 
    //for each module definition stored 
    var module = new modules[name](); 
    module.init(); 
} 

nun Event-Handler auf die Elemente gebunden sind. Das funktioniert, wenn das Modul html bereits auf der Seite ist. Wenn ich jedoch versuche, eine weitere Kopie des HTML-Codes dieses Moduls zu laden, die noch keine Handler hat, ruft der Aufruf start() die Handler auf, aber jetzt verdoppelt sich der Handler für den vorhandenen/bereits initialisierten HTML-Code. Wenn Sie auf die Schaltfläche im vorinstallierten HTML klicken, werden Klickereignisse zweimal ausgelöst.

Ich kann diese Magie auf die Moduldefinition nicht tun. Ich muss das Format "Konstruktor/Callback-Funktion" beibehalten. Außerdem möchte ich nicht, dass Benutzer Workarounds dafür tun. Dies muss unter dem Rahmen-Code erfolgen.

Wie führe ich das Modulskript nur für den neu hinzugefügten, exakt identischen HTML aus?

oder

Wie verhindere ich das Skript aus dem bereits initialisiert HTML zu beeinflussen?

+0

starten Haben Sie einen Parameter übernehmen, und wenn das null dann alles tun, sollte Ihr Problem lösen. –

Antwort

2

Zwei Antworten auf das Dilemma: jQuerys Auswahlbereich oder Ereignisdelegierung.

Im ersten Fall, Sie könnten Ihre Wähler nur in Ihrem Modul, von einer bestandenen context greifen Elemente stellen Sie sicher, dass: modifizierenden

framework.module.create('module_name',function(context){ 

    if (!context) { 
     context = document; 
    } 

    //execute when starting the module 
    this.init = function(){ 

     //for example, bind a click handler 
     $('button', context).on('click',function(){ 
      alert('foo'); 
     }); 
    } 
}); 

Aber in diesem Beispiel start müßte auch, sein eigenes context Argument zu nehmen, und es zusammen mit dem Modul übergeben:

function start(context){ 
    //for each module definition stored 
    var module = new modules[name](context); 
    module.init(); 
} 

Sie würden dann verwenden, etwa so: start("#myDiv");. Und für den Fall, dass Sie keinen Kontext übergeben, würde es automatisch die document für seinen Selektor-Kontext greifen. Ich bin mir jedoch nicht sicher, ob Sie das tun wollen, indem Sie bei jedem Aufruf etwas anderes an start übergeben.

Oder ... könnten Sie Delegierung verwenden:

framework.module.create('module_name',function(){ 

    //execute when starting the module 
    this.init = function(){ 

     //for example, bind a click handler 
     $(document).on('click', 'button', function(){ 
      alert('foo'); 
     }); 
    } 
}); 

Dies legt den Event-Handler zum document Objekt, und es läuft, wenn es sieht, dass seine Blase Kette durch eine 'button' bestanden hat. Dies fügt jedoch den Ereignishandler jedes Mal hinzu, wenn module.init aufgerufen wird. So können Sie einen Zähler mit dem Modul-Konstruktor hinzufügen, werden nur die Ereignisbehandlungsroutine zugeordnet werden, wenn dies das erste Objekt:

framework.module.create('module_name',function(){ 
    var totalModules = 0; 
    return function(){ 

     totalModules += 1; 
     //execute when starting the module 
     this.init = function(){ 

      // if this is the first module being created, and 
      // no event handlers have yet been attached... 
      if (totalModules === 1) { 
       $(document).on('click', 'button', function(){ 
        alert('foo'); 
       }); 
      } 
     } 
    } 
}()); 
Verwandte Themen