2009-04-22 15 views
13

Ho un bug di IE che non sono sicuro di come risolvere.IE7 e 8 non vengono attivati ​​jQuery eventi di clic per gli elementi aggiunti all'interno di una tabella

Uso di jQuery Muovere dinamicamente un menu per apparire su un elemento al passaggio del mouse.

Il mio codice (semplificato) simile a questa:

$j = jQuery.noConflict(); 

$j(document).ready(function() 
{ 
    //do something on the menu clicks 
    $j('div.ico').click(function() { alert($j(this).parent().html()); }); 

    setUpActions('#tableId', '#menuId'); 
}); 

//on mouseover set up the actions menu to appear on mouseover 
function setUpActions(tableSelector, menuSelector) 
{ 
    $j(tableSelector + ' div.test').mouseover(function() 
    { 
     //note that append will move the underlying 
     //DOM element with all events from it's old 
     //parent to the end of this one. 
     $j(this).append($j(menuSelector).show()); 
    }); 
} 

Questo menu non sembra registrare gli eventi in modo corretto per il menu dopo che è stato spostato in IE7, IE8 e IE8-as-IE7 (yeah MS, questo è davvero un "nuovo motore di rendering" in IE8, vi crediamo tutti).

Funziona come previsto in tutto il resto.

È possibile visualizzare il comportamento in a basic demo here.

Nella demo si possono vedere due esempi della questione:

  1. L'immagine dietro i pulsanti dovrebbe cambiare al passaggio del mouse (fatto con i CSS: selettore hover). Funziona sul primo mouseover ma poi persiste.
  2. L'evento click non viene attivato, tuttavia con gli strumenti dev è possibile chiamarlo manualmente ed è ancora registrato.

Si può vedere (2) in strumenti di sviluppo di IE8:

  1. aperto page in IE8
  2. strumenti Open dev
  3. Selezionare "Script" linguetta e "Console" sotto-scheda
  4. Tipo: $j('#testFloat div.ico:first').click() per chiamare manualmente qualsiasi evento sottoscritto
  5. Ci sarà un avviso nella pagina

Ciò significa che sono non perdere le sottoscrizioni degli eventi, sono ancora lì, IE non li chiama semplicemente quando faccio clic.

Qualcuno sa perché questo errore si verifica (oltre che solo per il motore venerabile di IE)?

C'è una soluzione?

Potrebbe essere qualcosa che sto sbagliando che semplicemente funziona come previsto in tutto il resto?

risposta

10

Stranamente, anche se l'evento click non viene attivato in IE, se lo si cambia in mouse o mouse su funziona come ci si aspetterebbe, anche se si ha ancora il problema del passaggio del mouse sull'immagine.

$j('div.ico').mouseup(function() { alert($j(this).parent().html()); }); 
+0

Bel trucco: funziona! Nonostante 'hover' sia originariamente un'estensione IE, penso che accetterò semplicemente che non funziona qui. Saluti! – Keith

0

Consiglio vivamente di utilizzare gli eventi dal vivo invece dell'ultima jquery.

questo modo è possibile associare agli elementi di classe CSS che non sono stati creati all'inizio, ma sarà aggiunto l'associazione clic quando vengono aggiunti nuovi elementi:

http://docs.jquery.com/Events/live

+1

Grazie, buona idea, ma ci ho provato e non fa differenza. Non ho perso l'evento click - $ j ('selector'). Click() nella riga di comando javascript genererà l'evento che mi aspetto. L'abbonamento all'evento jQuery è sopravvissuto alla mossa, è solo che IE non sembra chiamarlo. Il CSS: hover ha gli stessi sintomi. – Keith

+0

hai una pagina demo che posso guardare? – Richard

+0

Sì, il link è nella domanda. – Keith

1

IE non copia eventi agli elementi aggiunti dinamicamente al DOM.

Prova ad associare l'evento click dopo aver aggiunto ciò che è necessario associare o utilizzare.live()

se si utilizza clone() ricordarsi di passare clone (true) per richiedere esplicitamente la copia di gestori di eventi.

var actionMenu = $j(menuSelector); 

//actionMenu is now an Instance of jQuery, not the DOM object 
//because jQuery is chainable 

actionMenu.hide(); 

// notice the clone(true) 

$j(this).append(actionMenu.clone(true)); 

jQuery è chainable, in modo da poter anche scrivere questo nella sintassi "jQuery" come:

var clone = $j(menuSelector) 
       .clone(true) 
       .css('background-color', $j(this).css('background-color')); 

$j(this).append(clone); 

Non credo che è necessario mostra/nascondi quanto accade così in fretta.

+0

Come puoi vedere dal codice di esempio nella domanda e dalla demo di lavoro a cui sto collegando non sto usando clone(). @ richard.grundy ha suggerito di usare live(), ma questo non fa differenza. Proverò a ri-legare gli eventi - vedi se questo ha qualche effetto. – Keith

+0

Ora testato: il riavvolgimento dell'evento click non lo risolve. Posso chiamare manualmente l'evento: andare alla demo online, aprire la console javascript dello strumento Dev di IE8 e chiamare $ j ('# testFloat div.ico'). Click() - l'azione che ho sottoscritto verrà quindi attivata. – Keith

+0

Il mio esempio è codice semplificato - nella demo live ho una tabella molto più grande e molti altri script in corso. Non voglio clonare l'elemento a meno che non sia necessario. Ma ho provato questo e ha lo stesso problema: gli elementi clonati possono mantenere l'evento con live() o re-binding, ma ciò non risolve il problema iniziale di IE che non registrava gli eventi di click o hover effettivi. – Keith

2

Ho avuto lo stesso problema, ma nessuna delle soluzioni precedenti funzionava. Il problema si è verificato che IE7 (non ho testato altre versioni di IE) non registrerà il file .click se è incatenato dopo una funzione di animazione. Quindi questo sarà NON lavoro:

$("div.menubar-item").animate({ 
    color:"#000" 
}, 0) 

.click(function() 
{ 
    //not firing 
}) 

Ma questo WILL lavoro

$("div.menubar-item").click(function() 
{ 
    //firing! 
}) 

$("div.menubar-item").animate({ 
    color:"#000" 
}, 0) 

EDIT: Lo stesso vale per MouseEnter, mouseLeave, ecc

EDIT 2: Attiva ancora gli eventi e si anima se si concatena la funzione di animazione DOPO il clic, quindi s è "valido" anche:

$("div.menubar-item").click(function() 
{ 
    //firing! 
}) 

.animate({ 
    color:"#000" 
}, 0) 
+0

WOW! Questo ha funzionato davvero. Spostando la mia dichiarazione di evento all'inizio del mio allegato, è stato risolto il problema. STRANO. Nota per gli altri: stavo usando l'evento .on(). – mrbinky3000

+1

AGGIORNAMENTO: ho fatto qualche ricerca in più e ho scoperto che IE stava incontrando un errore PRIMA della mia dichiarazione di evento e ho smesso di cercare di analizzare qualsiasi javascript passato quel punto. Quindi, spostando il trigger dell'evento nella parte superiore del mio script, ho risolto il problema del trigger. Tuttavia, correggere il bug in IE significava che avrei potuto riportare il trigger del mio evento nella sua posizione originale e che tutto funzionava correttamente. Morale della storia: UTILIZZA STRUMENTI SVILUPPATORE DI IE. Controlla la console per vedere se ci sono errori. – mrbinky3000

+0

Ottimo! Bella scoperta :-) – altschuler

Problemi correlati