jQuery attr vs prop?

102

Agora, esta não é apenas outra questão de qual é a diferença , eu fiz alguns testes (http://jsfiddle.net/ZC3Lf/) modificando o prope attrde <form action="/test/"></form>​ com a saída sendo:

1) Teste de modificação de prop.
Prop: http://fiddle.jshell.net/test/1
Attr:http://fiddle.jshell.net/test/1

2) Teste de modificação de atributo
Prop: http://fiddle.jshell.net/test/1
Attr:/test/1

3) Teste de modificação de atributo, em seguida,
Prop: http://fiddle.jshell.net/test/11
Atr:http://fiddle.jshell.net/test/11

4) Teste de Modificação de Prop, em seguida,
Prop: http://fiddle.jshell.net/test/11
Attr:http://fiddle.jshell.net/test/11

Agora estou confuso sobre algumas coisas, tanto quanto meu conhecimento vai:
Prop: O valor em seu estado atual após qualquer modificação via JavaScript
Attr: O valor como foi definido no html no carregamento da página.

Agora, se isso estiver correto,

  • Por que modificar o propparece torná-lo actiontotalmente qualificado e, inversamente, por que modificar o atributo não?
  • Por que modificar o propin 1)modifica o atributo, que não faz sentido para mim?
  • Por que modificar o attrem 2)modifica a propriedade, eles devem ser vinculados dessa forma?


Código de Teste

HTML

JavaScript

var element = $('form');
var property = 'action';

/*You should not need to modify below this line */

var body = $('body');
var original = element.attr(property);

body.append('<h1>Prop Modification test</h1>');
element.prop(property, element.prop(property) + 1);

body.append('Prop: '+element.prop(property)+'<br />');
body.append('Attr: '+element.attr(property)+'<hr />');

//reset
element.prop(property, original);
element.attr(property, original);

body.append('<h1>Attr Modification test</h1>');
element.attr(property, element.attr(property) + 1);

body.append('Prop: '+element.prop(property)+'<br />');
body.append('Attr: '+element.attr(property)+'<hr />');

//reset
element.prop(property, original);
element.attr(property, original);

body.append('<h1>Attr then Prop Modification test</h1>');
element.attr(property, element.attr(property) + 1);
element.prop(property, element.prop(property) + 1);

body.append('Prop: '+element.prop(property)+'<br />');
body.append('Attr: '+element.attr(property)+'<hr />');

//reset
element.prop(property, original);
element.attr(property, original);

body.append('<h1>Prop then Attr Modification test</h1>');
element.prop(property, element.prop(property) + 1);
element.attr(property, element.attr(property) + 1);

body.append('Prop: '+element.prop(property)+'<br />');
body.append('Attr: '+element.attr(property)+'<hr />');
Hailwood
fonte
3
Possível duplicata de stackoverflow.com/questions/5874652/prop-vs-attr
goodeye

Respostas:

71

Infelizmente, nenhum de seus links funciona :(

Alguns insights, porém, attrsão para todos os atributos. propé para propriedades.

Em versões mais antigas do jQuery (<1.6), nós apenas tínhamos attr. Para chegar a propriedades DOM como nodeName, selectedIndexou defaultValuevocê tinha que fazer algo como:

var elem = $("#foo")[0];
if ( elem ) {
  index = elem.selectedIndex;
}

Isso foi péssimo, então propfoi adicionado:

index = $("#foo").prop("selectedIndex");

Isso era ótimo, mas irritantemente isso não era compatível com versões anteriores, como:

<input type="checkbox" checked>

não tem atributo de checked, mas tem uma propriedade chamada checked.

Então, na versão final do 1.6, attrtambém faz proppara que as coisas não quebrem. Algumas pessoas queriam que fosse uma ruptura limpa, mas acho que a decisão certa foi tomada porque as coisas não quebraram em todos os lugares!

A respeito de:

Prop: o valor em seu estado atual após quaisquer modificações via JavaScript

Attr: o valor conforme definido no html no carregamento da página.

Isso nem sempre é verdade, pois muitas vezes o atributo é realmente alterado, mas para propriedades como as marcadas, não há um atributo a ser alterado, então você precisa usar prop.

Referências:

http://blog.jquery.com/2011/05/03/jquery-16-released/

http://ejohn.org/blog/jquery-16-and-attr

Rich Bradshaw
fonte
O link para o teste estava em "feito alguns testes" acima, vou torná-lo mais visível, mas aqui está: jsfiddle.net/ZC3Lf
Hailwood
Encontro uma dúvida, se o atributo for personalizado, não as propriedades DOM, prop () retorna undefinede attr () funciona bem.
rodovia
3

É um caso claro para ver as diferenças entre .prop e .attr

considere o HTML abaixo:

<form name="form" action="#">
    <input type="text" name="action" value="myvalue" />
    <input type="submit" />
</form>
<pre id="return">
</pre>

e o JS abaixo usando jQuery:

$(document).ready(function(){
    $("#return").append("$('form').prop('action') : " + $('form').prop('action') + '\r\n');
    $("#return").append("$('form').attr('action') : " + $('form').attr('action') + '\r\n');
    $("#return").append("document.form.action : " + document.form.action);
});

cria a seguinte saída:

$('form').prop('action') : [object HTMLInputElement]
$('form').attr('action') : #
document.form.action : [object HTMLInputElement]
SmasherHell
fonte
1

Eu tentei isso

console.log(element.prop(property));
console.log(element.attr(property));

e sai como abaixo

http://fiddle.jshell.net/test/
/test/ 

isso pode indicar que o actioné normalizado apenas quando é lido com prop.

Haocheng
fonte
Acho que não, senão a saída 2)seria normalizada!
Hailwood
@Hailwood Não vai, porque você obteve /test/quando acessar e attr, em seguida, definir /test/1para attr, que é o atributo do elemento. Não existe nenhum procedimento que desencadeie a normalização.
Haocheng
Estou confuso quanto ao que você quer dizer, o teste 2)acima é: element.attr(property, element.attr(property) + 1); body.append('Prop: '+element.prop(property)+'<br />'); body.append('Attr: '+element.attr(property)+'<hr />'); Se fosse normalizado quando lido, a linha final não geraria a versão normalizada?
Hailwood
Variáveis:property = 'action'; body = $('body'); element = $('form');
Hailwood
A normalização só será acionada quando prop for acessado, e o acesso de attr não.
Haocheng
1

desde jquery 1.6.1+ attr () retorna / altera propriedade como antes de 1.6. portanto, seus testes não fazem muito sentido.

esteja ciente de pequenas alterações nos valores de retorno.

por exemplo

attr ('verificado'): antes de 1.6 verdadeiro / falso é retornado, desde 1.6.1. “Verificado” / indefinido é retornado.

attr ('selecionado'): antes de 1.6 verdadeiro / falso ser retornado, pois 1.6.1 “selecionado” / indefinido é retornado

uma visão geral detalhada deste tópico em alemão pode ser encontrada aqui:

http://mabraham.de/jquery-prop-attr-val-richtig-verwenden/

Martin Abraham
fonte