2011-10-24 2 views
7

Ecco il mio HTML:Come posso capire questo comportamento della casella?

<input class='user_roles' id="chk" type=checkbox />
<input id="btn_on" type="button" value="on" />
<input id="btn_off" type="button" value="off" />

E il mio jQuery:

$('#chk').click(function() { 
    if($(this).prop("checked") === true) { 
     alert ("checked"); 
    } 
    else{ 
     alert ("not checked"); 
    } 
}); 

$("[id$=btn_on]").click(function() { 
    $('#chk').click(); 
}); 

$("[id$=btn_off]").click(function() { 
    $('#chk').click(); 
}); 

Un esempio di lavoro è here.

Quando si fa clic sulla casella di controllo con il mouse, viene immediatamente verificata, ovvero l'avviso visualizza "controllato". Tuttavia, quando viene fatto clic su uno dei pulsanti, che indirettamente chiama il metodo di clic sulla casella di controllo, la casella di controllo non viene selezionata fino a dopo il il codice di clic è stato eseguito.

Per verificare ciò, fare clic sulla casella di controllo un paio di volte con il mouse e verranno visualizzati rispettivamente gli avvisi "controllato" e "non selezionato". Fai clic su "On" e vedrai l'avviso "non selezionato", quindi la casella di controllo diventa selezionata. Se fai clic su "Off", vedrai "checked" seguito dalla casella di controllo deselezionata.

Qual è il motivo di questo comportamento? Come posso assicurarmi che la casella di controllo "verifica" avvenga prima che venga chiamato il codice listener dei clic, come da comportamento del mouse?

+0

Cosa stai cercando di uscire da questo? Avere un pulsante "on/off" per una 'checkbox' sembra un po 'ridondante. – Jack

+1

@Jack, è un esempio molto semplificato. Ho un click listener su più checkbox e un pulsante per controllarli tutti in una volta, quindi perché ho bisogno di sapere che l'azione di controllo avviene prima del codice click. –

risposta

4

se solo una questione di ottenere farlo funzionare, utilizzare .change() invece di .click() tua casella di controllo, se la sua sul perché fa quello che fa non ho idea dispiace

2

Provare a utilizzare setTimeout che attenderà un po 'e quindi controllarlo. Il problema è che l'evento si innesca ancora più velocemente di quanto la casella di controllo sia attivata per ragioni sconosciute.

Working fiddle

$('#chk').click(function() { 
    var $this = $(this); 
    setTimeout(function() { 
     if ($this.prop("checked") === true) { 
      alert("checked"); 
     } 
     else { 
      alert("not checked"); 
     } 
    }, 10); 
}); 

$("[id$=btn_on]").click(function() { 
    $('#chk').click(); 
}); 

$("[id$=btn_off]").click(function() { 
    $('#chk').click(); 
}); 
0

Ho trovato questo answer on Stack Overflow che crea manualmente un evento e lo invia.

Si può mettere in una funzione e chiamare da eventi click:

function simulateClick(target) 
{ 
    var e = document.createEvent('MouseEvents'); 
    e.initEvent('click', true, true); 
    target.dispatchEvent(e); 
} 

$("[id$=btn_on]").bind("click", function() { 
    simulateClick($('#chk')[0]); 
}); 

$("[id$=btn_off]").click(function() { 
    simulateClick($('#chk')[0]); 
}); 

Provalo qui: http://jsfiddle.net/FCrSg/10/

Quasi lo stesso di quello che si voleva il MDN: https://developer.mozilla.org/en/DOM/dispatchEvent_example

0

Si potrebbe fare:

function alertState(el){ 
    if(el.prop("checked") === true) { 
     alert ("checked"); 
    } 
    else{ 
     alert ("not checked"); 
    } 
} 
$('#chk').click(function() { 
    alertState($(this)); 
}); 
    $("[id$=btn_on]").click(function() { 
     $('#chk').prop('checked', true); 
     alertState($('#chk')); 
    }); 

    $("[id$=btn_off]").click(function() { 
      $('#chk').removeProp('checked'); 
     alertState($('#chk')); 
    }); 

qui violino qui http://jsfiddle.net/FCrSg/9/

2

utilizzare l'evento onchange posto del onclick:

http://jsfiddle.net/FCrSg/8/

L'evento onclick viene attivato quando la casella viene cliccato prima che il valore della scatola è cambiato.

Il flusso di lavoro è simile a questo: si fa clic su di voi del mouse => evento OnClick viene licenziato => casella di controllo viene selezionata => OnChange evento viene generato

+0

Non penso che il flusso di lavoro sia corretto. Quando si fa clic sulla casella di controllo con il mouse, viene registrato come selezionato quando viene eseguito il codice onclick. Non lo fa quando chiami il metodo click nel codice. Ma tu e Blem avete ragione sul cambiamento dell'evento. –

1

Fisicamente cliccando sulla casella di controllo fa sì che già essere controllata prima l'evento click viene attivato.Usando jquery per fare clic, viene eseguito prima il codice evento. Usando l'evento change, invece, otterrai i risultati desiderati.

Vedere l'esempio di lavoro seguente.

http://jsfiddle.net/FCrSg/3/

1

Mi sembra le spiegazioni è che questo è un bug nel modo in cui il browser tratta clic su caselle di controllo:

Il comportamento di default dovrebbe aver luogo dopo il gestore di eventi personalizzato è chiamato . Quindi quello che vedi quando fai clic sui pulsanti è in realtà il comportamento corretto. Il comportamento divertente è che quando fai clic sulla casella viene controllato prima che venga eseguito il gestore di eventi personalizzato.

Per vedere come è strano, è possibile return false; dal gestore eventi. Questo dovrebbe impedire il comportamento predefinito. Quello che vedrai è che la casella viene effettivamente controllata quando fai clic su di essa - e quindi deselezionata una volta che il gestore di eventi restituisce!

A proposito, sto utilizzando Firefox 4. Non so come sia in altri browser. Sembra non essere correlato a jQuery, in quanto posso vedere lo stesso comportamento divertente quando si fa tutto senza di esso.