Manipulação de evento da caixa de seleção jQuery

136

Eu tenho o seguinte:

<form id="myform">
   <input type="checkbox" name="check1" value="check1">
   <input type="checkbox" name="check2" value="check2">
</form>

Como uso o jQuery para capturar qualquer evento de verificação ocorrendo myforme informar em qual caixa de seleção foi alternada (e saber se foi ativada ou desativada)?

aeq
fonte

Respostas:

243
$('#myform :checkbox').change(function() {
    // this will contain a reference to the checkbox   
    if (this.checked) {
        // the checkbox is now checked 
    } else {
        // the checkbox is now no longer checked
    }
});
Darin Dimitrov
fonte
30
thisjá está definido como o elemento DOM da caixa de seleção, portanto this.checkedé suficiente. Você não precisará criar outro objeto jQuery para ele, a menos que planeje manipulá-lo.
Walf
18
Apenas uma pequena dica. Você obterá um aumento de desempenho usando a caixa de seleção input: no seu seletor em vez de apenas a caixa de seleção: já que o último é traduzido para o seletor universal *: caixa de seleção.
jimmystormig
23
O clique não está nem perto de nenhum evento de verificação.
Peter Peter
27
Esta não é a melhor resposta. Se você tiver um rótulo correspondente para sua entrada (como <label for='myInput'>Checkbox:</label><input id='myInput' name='myInput' type='checkbox'/>) e clicar no rótulo, a caixa de seleção será marcada, mas essa função NÃO será chamada. Você deve usar o .change()evento
Patrick
7
Esta resposta não fornece a resposta completa - consulte a resposta da Anurag abaixo, que é uma resposta MUITO mais completa (e precisa). Esta resposta está parcialmente correta, é claro, mas como afirmado, não é a melhor resposta.
Carnix
131

Use o evento de mudança.

$('#myform :checkbox').change(function() {
    // this represents the checkbox that was checked
    // do something with it
});
Anurag
fonte
5
Se a caixa de seleção estiver oculta, o usuário não poderá interagir com ela. Deixe-me saber se você quis dizer outra coisa.
Anurag
1
Isso não dispara para $("input[name=check1]").prop('checked', true). Veja jsfiddle.net/Z3E8V/2
Peter
15
Isso é por design. Alterar programaticamente a propriedade de um elemento DOM não aciona manipuladores de eventos associados. Você terá que acioná-los manualmente.
Anurag
6
Esta deve ser a resposta selecionada, que abrange clicando rótulo de um checkbox
Patrick
3
Na documentação do jQuery: "Como :checkboxé uma extensão do jQuery e não faz parte da especificação CSS, as consultas que usam :checkboxnão podem tirar proveito do aumento de desempenho fornecido pelo querySelectorAll()método DOM nativo . Para obter um melhor desempenho nos navegadores modernos, use [type="checkbox"]".
NXT
54

Existem várias respostas úteis, mas nenhuma parece cobrir todas as opções mais recentes . Para esse fim, todos os meus exemplos também atendem à presença de labelelementos correspondentes e permitem adicionar dinamicamente caixas de seleção e ver os resultados em um painel lateral (redirecionando console.log).

  • Escutar clickeventos ativados nãocheckboxes é uma boa ideia, pois isso não permitirá a alternância do teclado ou as alterações feitas no local em que um elemento correspondente foi clicado. Sempre ouça o evento.labelchange

  • Use o :checkboxpseudo-seletor do jQuery , em vez de input[type=checkbox]. :checkboxé mais curto e mais legível.

  • Use is()com o :checkedpseudo-seletor do jQuery para testar se uma caixa de seleção está marcada. Isso garante que funcione em todos os navegadores.

Manipulador de eventos básico anexado aos elementos existentes:

$('#myform :checkbox').change(function () {
    if ($(this).is(':checked')) {
        console.log($(this).val() + ' is now checked');
    } else {
        console.log($(this).val() + ' is now unchecked');
    }
});

JSFiddle: http://jsfiddle.net/TrueBlueAussie/u8bcggfL/2/

Notas:

  • Usa o :checkboxseletor, que é preferível a usarinput[type=checkbox]
  • Isso se conecta apenas aos elementos correspondentes existentes no momento em que o evento foi registrado.

Manipulador de eventos delegados anexado ao elemento ancestral:

Os manipuladores de eventos delegados são projetados para situações em que os elementos ainda não podem existir (carregados ou criados dinamicamente) e são muito úteis. Eles delegam responsabilidade a um elemento ancestral (daí o termo).

$('#myform').on('change', ':checkbox', function () {
    if ($(this).is(':checked')) {
        console.log($(this).val() + ' is now checked');
    } else {
        console.log($(this).val() + ' is now unchecked');
    }
});

JSFiddle: http://jsfiddle.net/TrueBlueAussie/u8bcggfL/4/

Notas:

  • Isso funciona ouvindo eventos (neste caso change) para formar bolhas até um elemento ancestral que não muda (nesse caso #myform).
  • Em seguida, aplica o seletor jQuery ( ':checkbox'neste caso) apenas aos elementos na cadeia de bolhas .
  • Em seguida, aplica a função de manipulador de eventos apenas aos elementos correspondentes que causaram o evento.
  • Use documentcomo padrão para conectar o manipulador de eventos delegados, se nada mais estiver mais próximo / conveniente.
  • Não use bodypara anexar eventos delegados, pois ele possui um bug (relacionado ao estilo) que pode impedir a obtenção de eventos do mouse.

O resultado dos manipuladores delegados é que os elementos correspondentes precisam existir apenas no momento do evento e não quando o manipulador de eventos foi registrado. Isso permite que o conteúdo adicionado dinamicamente gere os eventos.

P: É mais lento?

R: Enquanto os eventos estiverem na velocidade de interação do usuário, você não precisa se preocupar com a diferença insignificante de velocidade entre um manipulador de eventos delegado e um manipulador conectado diretamente. Os benefícios da delegação superam largamente qualquer desvantagem menor. Os manipuladores de eventos delegados são realmente mais rápidos para registrar , pois geralmente se conectam a um único elemento correspondente.


Por que não prop('checked', true)dispara o changeevento?

Isso é realmente por design. Se ele disparasse o evento, você facilmente entraria em uma situação de infinitas atualizações. Em vez disso, depois de alterar a propriedade marcada, envie um evento de mudança para o mesmo elemento usando trigger(não triggerHandler):

por exemplo, sem triggernenhum evento ocorre

$cb.prop('checked', !$cb.prop('checked'));

JSFiddle: http://jsfiddle.net/TrueBlueAussie/u8bcggfL/5/

por exemplo, com triggero evento normal de mudança é capturado

$cb.prop('checked', !$cb.prop('checked')).trigger('change');

JSFiddle: http://jsfiddle.net/TrueBlueAussie/u8bcggfL/6/

Notas:

  • Não use triggerHandlercomo sugerido por um usuário, pois ele não fará bolhas de eventos para um manipulador de eventos delegados .

JSFiddle: http://jsfiddle.net/TrueBlueAussie/u8bcggfL/8/

embora irá trabalhar para um manipulador de eventos diretamente ligado ao elemento:

JSFiddle: http://jsfiddle.net/TrueBlueAussie/u8bcggfL/9/

Eventos acionados com .triggerHandler () não fazem bolhas na hierarquia do DOM; se não forem tratados diretamente pelo elemento de destino, eles não farão nada.

Referência: http://api.jquery.com/triggerhandler/

Se alguém tiver recursos adicionais que considerem não abrangidos por isso, sugira adições .

Gone Coding
fonte
31

Usando o novo método 'on' no jQuery (1.7): http://api.jquery.com/on/

    $('#myform').on('change', 'input[type=checkbox]', function(e) {
        console.log(this.name+' '+this.value+' '+this.checked);

    });
  • o manipulador de eventos permanecerá
  • capturará se a caixa de seleção foi alterada pelo teclado, não apenas clique
Allen Hamilton
fonte
1
Isso não dispara para $("input[name=check1]").prop('checked', true). Veja jsfiddle.net/Z3E8V/2
Peter
7
Basta adicionar .triggerHandler('change');após a .propchamada. Em seguida, alternará a caixa E chamará o evento.
26413 Hanna
5
$('#myform input:checkbox').click(
 function(e){
   alert($(this).is(':checked'))
 }
)
Pensador
fonte
val()não diz se checkedé true.
Walf
5

Reconhecendo o fato de que o solicitante solicitou especificamente o jQuery e de que a resposta selecionada está correta, deve-se notar que esse problema realmente não precisa do jQuery, por exemplo. Se alguém deseja resolver esse problema sem ele, pode simplesmente definir o onClickatributo das caixas de seleção nas quais deseja adicionar funcionalidades adicionais, como:

HTML:

<form id="myform">
  <input type="checkbox" name="check1" value="check1" onClick="cbChanged(this);">
  <input type="checkbox" name="check2" value="check2" onClick="cbChanged(this);">
</form>

javascript:

function cbChanged(checkboxElem) {
  if (checkboxElem.checked) {
    // Do something special
  } else {
    // Do something else
  }
}

Fiddle: http://jsfiddle.net/Y9f66/1/

Chase Sandmann
fonte
5
Colocar manipuladores de eventos diretamente no HTML funciona, é claro. Mas está em conflito direto com as metodologias DRY e de aprimoramento progressivo. Uma resposta mais precisa seria "Você não precisa do jQuery para adicionar manipuladores de eventos". Em vez disso, use o JS padrão para anexar os manipuladores de clique em um arquivo JS separado, em vez de colocar atributos onclick no HTML. Fazer isso "funciona", mas as boas práticas de codificação determinam que você deve evitá-lo sempre que possível (o que é quase sempre nesse momento, a menos que você deva dar suporte ao IE6 ou algo assim, que até a MS diz que não deve mais fazer)
Carnix
3

Eu tentei o código da primeira resposta, ele não está funcionando, mas eu brinco e esse trabalho para mim

$('#vip').change(function(){
    if ($(this).is(':checked')) {
        alert('checked');
    } else {
        alert('uncheck');
    }
});
Somwang Souksavatd
fonte