Por que o checkbox enlouquece? História de um bug
\n\nImagine: você está escrevendo um formulário de cadastro em um site. Há um checkbox "Concordo com os termos". O usuário clica — a marca aparece. Tudo funciona. Mas aí você decide adicionar um botão "Marcar todos" com jQuery. Escreve $('#agree').attr('checked', true) — e... nada acontece. Ou a marca aparece uma vez, mas depois não sai mais. Familiar?
Essa pergunta é uma das mais populares no Stack Overflow. Milhares de desenvolvedores tropeçam no mesmo erro. E hoje vamos entender por que isso acontece e como definir corretamente o checked para checkbox com jQuery.
\n\nResumindo: qual é o problema?
\n\nO problema é que muitos iniciantes (e não só eles) usam o método .attr() para controlar o atributo checked. Mas a partir do jQuery 1.6, a forma correta é usar .prop(). A diferença entre atributo (attribute) e propriedade (property) é o tema chave que vamos explicar agora.
Atributo vs Propriedade: qual a diferença?
\n\nVamos simplificar. O atributo HTML é o que você escreve na marcação:
\n\n<input type="checkbox" id="agree" checked>\n\nO atributo checked aqui define o estado inicial do checkbox. Mas quando o usuário clica — o que muda é a propriedade (property) do elemento DOM, enquanto o atributo permanece inalterado.
O método .attr() trabalha com atributos, e .prop() com propriedades. E como estamos interessados no estado atual do checkbox (que muda dinamicamente), precisamos usar .prop().
Como fica no código
\n\nAqui está um exemplo simples que demonstra a diferença:
\n\n<!-- HTML -->\n<input type="checkbox" id="myCheckbox">\n<button id="setChecked">Marcar</button>\n<button id="removeChecked">Desmarcar</button>\n\n<script>\n// Forma correta (jQuery 1.6+)\n$('#setChecked').click(function() {\n $('#myCheckbox').prop('checked', true);\n});\n\n$('#removeChecked').click(function() {\n $('#myCheckbox').prop('checked', false);\n});\n</script>\n\nObserve: passamos como segundo argumento true ou false — um valor booleano. Isso é importante.
Erros típicos de iniciantes (e como evitá-los)
\n\nErro 1: Usar .attr() para definir checked
\n\n// ❌ Incorreto\n$('#myCheckbox').attr('checked', true);\n\n// ❌ Também incorreto\n$('#myCheckbox').attr('checked', 'checked');\n\nPor que isso é ruim? Porque .attr() define o atributo, não a propriedade. Após o primeiro clique do usuário, o atributo pode permanecer, mas a propriedade muda. O resultado é um comportamento inconsistente.
Erro 2: Passar string em vez de valor booleano
\n\n// ❌ Incorreto\n$('#myCheckbox').prop('checked', 'true'); // string, não booleano\n\nO jQuery converte string para booleano? Em alguns casos, sim. Mas confiar nisso é uma má prática. Sempre passe true ou false sem aspas.
Erro 3: Esquecer o .prop() ao ler o estado
\n\n// ❌ Incorreto\nif ($('#myCheckbox').attr('checked')) { ... }\n\n// ✅ Correto\nif ($('#myCheckbox').prop('checked')) { ... }\n\nPara ler o estado atual — use apenas .prop().
Exemplo completo: formulário com checkboxes e botões de controle
\n\nVamos juntar tudo. Imagine que temos uma lista de opções que o usuário pode selecionar, e botões "Selecionar todos" e "Desmarcar todos".
\n\n<!DOCTYPE html>\n<html>\n<head>\n <title>Gerenciamento de checkboxes com jQuery</title>\n <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>\n</head>\n<body>\n <h3