jQuery attr vs prop?

102

Maintenant, ce n'est pas juste une autre question Quelle est la différence , j'ai fait quelques tests (http://jsfiddle.net/ZC3Lf/) en modifiant le propet attrde <form action="/test/"></form>​ avec la sortie étant:

1) Test de modification de l'hélice
Prop: http://fiddle.jshell.net/test/1
Attr:http://fiddle.jshell.net/test/1

2) Test de modification Attr
Prop: http://fiddle.jshell.net/test/1
Attr:/test/1

3) Attr puis Prop Modification test
Prop: http://fiddle.jshell.net/test/11
Attr:http://fiddle.jshell.net/test/11

4) Prop puis Attr Modification test
Prop: http://fiddle.jshell.net/test/11
Attr:http://fiddle.jshell.net/test/11

Maintenant, je suis confus sur deux ou trois choses, pour autant que je sache:
Prop: La valeur dans son état actuel après toute modification via JavaScript
Attr: La valeur telle qu'elle a été définie dans le html au chargement de la page.

Maintenant, si c'est correct,

  • Pourquoi modifier le propsemble - t-il rendre le actionpleinement qualifié, et inversement pourquoi ne pas modifier l'attribut?
  • Pourquoi modifier le propin 1)modifie-t-il l'attribut, celui-là n'a aucun sens pour moi?
  • Pourquoi modifier le attrin 2)modifie-t-il la propriété, sont-ils censés être liés de cette façon?


Code de test

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
la source
3
Double

Réponses:

71

Malheureusement, aucun de vos liens ne fonctionne :(

Cependant, certaines informations attrconcernent tous les attributs. propest pour les propriétés.

Dans les anciennes versions de jQuery (<1.6), nous venons d'avoir attr. Pour obtenir des propriétés DOM telles que nodeName, selectedIndexou defaultValueil fallait faire quelque chose comme:

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

Cela a sucé, a donc propété ajouté:

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

C'était génial, mais malheureusement ce n'était pas rétrocompatible, car:

<input type="checkbox" checked>

n'a pas d'attribut de checked, mais il a une propriété appelée checked.

Donc, dans la version finale de la 1.6, attrfaites aussi proppour que les choses ne se cassent pas. Certaines personnes voulaient que ce soit une pause nette, mais je pense que la bonne décision a été prise car les choses ne se sont pas cassées partout!

En ce qui concerne:

Prop: La valeur dans son état actuel après toute modification via JavaScript

Attr: La valeur telle qu'elle a été définie dans le code HTML lors du chargement de la page.

Ce n'est pas toujours vrai, car l'attribut est souvent modifié, mais pour les propriétés telles que cochées, il n'y a pas d'attribut à modifier, vous devez donc utiliser prop.

Références:

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

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

Rich Bradshaw
la source
Le lien vers le test était sur "fait quelques tests" ci-dessus, je vais le rendre plus visible, mais le voici quand même: jsfiddle.net/ZC3Lf
Hailwood
Je trouve une question, si l'attribut est personnalisé, pas les propriétés DOM, prop () retourne undefinedet attr () fonctionne bien.
hiway
3

Il y a un cas clair pour voir les différences entre .prop et .attr

considérez le HTML ci-dessous:

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

et le JS ci-dessous en utilisant 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);
});

crée la sortie suivante:

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

J'ai essayé ça

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

et il sort comme ci-dessous

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

cela peut indiquer que le actionn'est normalisé que lorsqu'il est lu avec prop.

Haocheng
la source
Je ne pense pas, sinon la sortie en 2)serait normalisée!
Hailwood
@Hailwood Ce ne sera pas le cas, car vous avez /test/accès à attr, puis défini /test/1sur attr, qui est l'attr de l'élément. Il n'y a aucune procédure qui déclenche la normalisation.
Haocheng
Je ne comprends pas ce que vous voulez dire, le test 2)ci-dessus est element.attr(property, element.attr(property) + 1); body.append('Prop: '+element.prop(property)+'<br />'); body.append('Attr: '+element.attr(property)+'<hr />'); Si c'était normalisé lors de la lecture, la dernière ligne ne produirait-elle pas la version normalisée?
Hailwood
Variables:property = 'action'; body = $('body'); element = $('form');
Hailwood
La normalisation ne sera déclenchée que lorsque l' accessoire sera accédé, et l'accès d'attr ne le sera pas.
Haocheng
1

puisque jquery 1.6.1+ attr () retourne / change la propriété comme avant 1.6. ainsi vos tests n'ont pas beaucoup de sens.

soyez conscient des changements mineurs dans les valeurs de retour.

par exemple

attr ('vérifié'): avant 1.6 vrai / faux est retourné, depuis 1.6.1. «Vérifié» / non défini est renvoyé.

attr ('selected'): avant 1.6 true / false est retourné, puisque 1.6.1 “selected” / undefined est retourné

un aperçu détaillé de ce sujet en allemand peut être trouvé ici:

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

Martin Abraham
la source