Come mantenere l'evento Javascript corretto dopo aver utilizzato cloneNode(true)
-
09-06-2019 - |
Domanda
Ho un elemento del modulo che contiene più righe di input.Pensa a ciascuna riga come agli attributi di un nuovo oggetto che voglio creare nella mia applicazione web.E voglio essere in grado di creare più nuovi oggetti in un POST HTTP.Sto utilizzando il metodo cloneNode(true) integrato di Javascript per clonare ogni riga.Il problema è che ogni riga di input ha anche un collegamento di rimozione allegato al suo evento onclick:
// prototype based
<div class="input-line">
<input .../>
<a href="#" onclick="$(this).up().remove();"> Remove </a>
</div>
Quando si fa clic sul collegamento di rimozione della riga di input clonata, vengono rimosse anche tutte le righe di input clonate dallo stesso oggetto dom.È possibile riassociare l'oggetto "this" al tag di ancoraggio corretto dopo aver utilizzato cloneNode(true) sull'elemento DOM sopra?
Soluzione
Non inserire il gestore su ogni collegamento (questo dovrebbe essere davvero un pulsante, a proposito).Utilizzo evento che ribolle gestire Tutto pulsanti con un gestore:
formObject.onclick = function(e)
{
e=e||event; // IE sucks
var target = e.target||e.srcElement; // and sucks again
// target is the element that has been clicked
if (target && target.className=='remove')
{
target.parentNode.parentNode.removeChild(target.parentNode);
return false; // stop event from bubbling elsewhere
}
}
+
<div>
<input…>
<button type=button class=remove>Remove without JS handler!</button>
</div>
Altri suggerimenti
Potresti provare a clonare utilizzando il metodo innerHTML o un mix:
var newItem = $(item).cloneNode(false);
newItem.innerHTML = $(item).innerHTML;
Anche:Penso che cloneNode non cloni gli eventi registrati con addEventListener.Ma gli eventi attachEvent di IE Sono clonato.Ma potrei sbagliarmi.
L'ho testato in IE7 e FF3 e ha funzionato come previsto: deve esserci qualcos'altro.
Ecco il mio script di prova:
<div id="x">
<div class="input-line" id="y">
<input type="text">
<a href="#" onclick="$(this).up().remove();"> Remove </a>
</div>
</div>
<script>
$('x').appendChild($('y').cloneNode(true));
$('x').appendChild($('y').cloneNode(true));
$('x').appendChild($('y').cloneNode(true));
</script>
Per eseguire il debug di questo problema, eseguirei il wrap del codice
$(this).up().remove()
in una funzione:
function _debugRemoveInputLine(this) {
debugger;
$(this).up().remove();
}
Ciò ti consentirà di scoprire cosa restituisce $ (questo).Se restituisce effettivamente più di un oggetto (più righe), allora sai sicuramente dove cercare: nel codice che crea l'elemento utilizzando cloneNode.Esegui qualche modifica dell'elemento risultante (ad es.cambiando l'attributo id)?
Se avessi il problema che stai descrivendo, prenderei in considerazione l'aggiunta di ID univoci all'elemento di attivazione e all'elemento "linea".
La prima risposta è quella corretta.
Pornel suggerisce implicitamente la soluzione più indipendente dal browser e dal framework.
Non l'ho testato, ma il concetto funzionerà in queste situazioni dinamiche che coinvolgono eventi.
Sembra che tu stia utilizzando jQuery?Ha un metodo per clonare un elemento con eventi: http://docs.jquery.com/Manipulation/clone#true
MODIFICARE:Spiacenti, vedo che stai utilizzando Prototype.