Introdução: por que este tópico é tão importante?
\nSe você já escreveu código jQuery que precisava obter ou definir o valor de um atributo em um elemento HTML, certamente já se deparou com dois métodos: .prop() e .attr(). À primeira vista, eles fazem a mesma coisa. Mas, na prática, a diferença entre eles é a fonte de centenas de bugs e milhares de perguntas no Stack Overflow.
Neste tutorial passo a passo, vamos entender de uma vez por todas as diferenças entre .prop() e .attr() em jQuery, quando usar cada um e como não cair em armadilhas. Escreveremos código real, observaremos o comportamento real do navegador e memorizaremos uma regra simples.
Este artigo não é uma documentação seca. É o seu guia pessoal sobre um dos tópicos mais confusos do jQuery.
\n\nResumindo: atributos vs propriedades
\nAntes de mergulharmos no código, vamos entender a teoria. No DOM (Modelo de Objeto de Documento), existem dois conceitos:
\n- \n
- Atributo (attribute) — o que está escrito no código HTML. Por exemplo,
<input type="checkbox" checked="checked">. Atributos são sempre strings. \n - Propriedade (property) — o que é armazenado no objeto do elemento DOM após o navegador ler o HTML. As propriedades podem ser de qualquer tipo de dado: string, booleano, número, objeto. \n
O método .attr() trabalha com atributos. O método .prop() trabalha com propriedades. Parece simples? Sim, mas há nuances.
A principal armadilha: atributos booleanos
\nO exemplo mais popular que confunde iniciantes são as caixas de seleção, botões de rádio e outros elementos com atributos booleanos (checked, disabled, selected, readonly).
Imagine que você tem este HTML:
\n<input type="checkbox" id="myCheckbox" checked>\nVocê quer verificar se a caixa de seleção está marcada. Logicamente, você escreveria assim:
\nconsole.log( $('#myCheckbox').attr('checked') ); // "checked" (string!)\nconsole.log( $('#myCheckbox').prop('checked') ); // true (booleano!)\nAí está a diferença! .attr() retorna a string "checked" se o atributo existir no HTML e undefined se não existir. Já .prop() retorna true ou false, dependendo do estado atual do elemento no DOM.
Agora, o mais interessante: o que acontece se o usuário desmarcar a caixa?
\n// Depois que o usuário desmarcou a caixa:\nconsole.log( $('#myCheckbox').attr('checked') ); // "checked"! (o HTML não mudou)\nconsole.log( $('#myCheckbox').prop('checked') ); // false (o estado mudou)\nÉ por isso que usar .attr() para verificar o estado de uma caixa de seleção é um erro. O atributo checked no HTML permanece inalterado, enquanto a propriedade checked no DOM muda dinamicamente. .prop() sempre fornece a resposta atual.
A regra prática
\nExiste uma regra simples que o ajudará a não errar:
\n- \n
- Use
.prop()quando precisar obter ou alterar o estado dinâmico de um elemento (por exemplo,checked,disabled,selected,valuede um input). \n - Use
.attr()quando precisar ler ou alterar um atributo estático do HTML (por exemplo,href,src,data-*,id,class). \n
Lembre-se: .prop() é para propriedades que mudam durante a execução. .attr() é para atributos definidos na marcação.
Exemplo passo a passo: trabalhando com disabled
\nVamos analisar outro caso clássico — um botão com o atributo disabled.
<button id="myButton" disabled>Clique em mim</button