2013-10-25 18 views
11

Perché il mio evento click è stato attivato due volte in jQuery?Perché il mio evento click è stato chiamato due volte in jQuery?

HTML

<ul class=submenu> 
    <li><label for=toggle><input id=toggle type=checkbox checked>Show</label></li> 
</ul> 

Javascript

$("ul.submenu li:contains('Show')").on("click", function(e) { 
    console.log("toggle"); 
    if ($(this).find("[type=checkbox]").is(":checked")) console.log("Show"); 
    else console.log("Hide"); 
}); 

Questo è ciò che ottengo in consolle:

toggle      menu.js:39 
Show      menu.js:40 
toggle      menu.js:39 
Hide      menu.js:41 


> $("ul.submenu li:contains('Show')") 
[<li>​           ] 
    <label for=​"toggle">​ 
     <input id=​"toggle" type=​"checkbox" checked>​ 
     "Show" 
    </label>​ 
</li>​ 
+0

Si attiva solo una volta quando provo qui http://jsfiddle.net/LRjUc/ –

+0

@DominicGreen: Dipende dal fatto che si Fai clic sull'etichetta o sulla casella di controllo (o su 'li'). Se fai clic sull'etichetta, almeno su Chrome, ottieni entrambi gli eventi. –

+0

Sì, è un po 'difficile da vedere, ma se si seleziona l'ultimo testo sulla console, è possibile vedere l'evento sparato due volte dopo. – shuji

risposta

25

Se non ricordo male, ho visto questo comportamento su almeno un po ' browser, dove facendo clic sullo labelentrambi attiva un clic su labele su input.

Quindi se si ignorano gli eventi in cui e.target.tagName è "LABEL", verrà visualizzato solo l'evento. Almeno, questo è quello che ottengo nei miei test:

+1

sì, hai ragione. Posso anche attivare l'evento solo per la casella di controllo $ ("ul.submenu li: contiene ('Mostra bordi') [tipo = casella di controllo]"). On ("clic", callback); , grazie mille per la tua risposta. – shuji

+0

@shuji: Ah, okay, pensavo che lo stavi collegando al 'li' per una ragione specifica. :-) –

+0

Non proprio, è solo che questa è la prima volta che uso la casella di controllo per i miei menu, quindi ero abituato a legare direttamente a li. – shuji

1

questo comportamento si verifica quando il tag input è strutturata all'interno della label tag:

<label for="toggle"><input id="toggle" type="checkbox" checked>Show</label> 

Se la casella input è posto al di fuori label, con l'uso degli attributi id e for, la cottura multipla dell'evento click non si verificherà:

<label for="toggle">Show</label> 
<input id="toggle" type="checkbox" checked> 
1

Si consiglia di utilizzare l'evento change sullo input[type="checkbox"], che verrà attivato una sola volta. Così come una soluzione al problema di cui sopra si potrebbe effettuare le seguenti operazioni:

$("#toggle").on("change", function(e) { 
    if ($(this).is(":checked")) 
    console.log("toggle: Show"); 
    else 
    console.log("toggle: Hide"); 
}); 

https://jsfiddle.net/ssrboq3w/

La versione vanilla JS usando querySelector che non è compatibile con le vecchie versioni di IE:

document.querySelector('#toggle').addEventListener('change',function(){ 
    if(this.checked) 
    console.log('toggle: Show'); 
    else 
    console.log('toggle: Hide'); 
}); 

https://jsfiddle.net/rp6vsyh6/

Problemi correlati