jQuery attr vs prop?

102

Ahora bien, esta no es solo otra pregunta ¿Cuál es la diferencia? He hecho algunas pruebas (http://jsfiddle.net/ZC3Lf/) modificando el propy attrde <form action="/test/"></form>​ con el resultado:

1)
Prop Prueba de modificación Prop: http://fiddle.jshell.net/test/1
Attr:http://fiddle.jshell.net/test/1

2) Prueba de modificación de atributos
Prop: http://fiddle.jshell.net/test/1
Attr:/test/1

3) Atributo, luego prueba de modificación de la propuesta
Prop: http://fiddle.jshell.net/test/11
Attr:http://fiddle.jshell.net/test/11

4) Prop y luego Attr Modificación de prueba
Prop: http://fiddle.jshell.net/test/11
Attr:http://fiddle.jshell.net/test/11

Ahora estoy confundido acerca de un par de cosas, en lo que respecta a mi conocimiento:
Prop: el valor en su estado actual después de cualquier modificación a través de JavaScript
Attr: el valor como se definió en el html al cargar la página.

Ahora si esto es correcto,

  • ¿Por qué modificar el prop parece hacer actionque el atributo esté completamente calificado y, a la inversa, por qué no modifica el atributo?
  • ¿Por qué modificar el prop en 1)modifica el atributo, ese no tiene sentido para mí?
  • ¿Por qué la modificación de attren 2)modifica la propiedad, están destinados a estar vinculados de esa manera?


Código de prueba

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 />');
Granizo
fuente
3
Posible duplicado de stackoverflow.com/questions/5874652/prop-vs-attr
goodeye

Respuestas:

71

Desafortunadamente, ninguno de sus enlaces funciona :(

Sin embargo, alguna información attres para todos los atributos. propes para propiedades.

En versiones anteriores de jQuery (<1.6), solo teníamos attr. Para llegar a propiedades DOM como nodeName, selectedIndexo defaultValueque tenía que hacer algo como:

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

Eso apestaba, así que propse agregó:

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

Esto fue genial, pero molestamente esto no era compatible con versiones anteriores, ya que:

<input type="checkbox" checked>

no tiene el atributo de checked, pero tiene una propiedad llamada checked.

Entonces, en la versión final de 1.6, attrtambiénprop para que las cosas no se rompan. Algunas personas querían que esto fuera una ruptura limpia, pero creo que se tomó la decisión correcta, ¡ya que las cosas no se rompieron por todos lados!

Respecto a:

Prop: el valor en su estado actual después de cualquier modificación a través de JavaScript

Attr: el valor tal como se definió en el html al cargar la página.

Esto no siempre es cierto, ya que muchas veces se cambia el atributo, pero para propiedades como check, no hay ningún atributo para cambiar, por lo que debe usar prop.

Referencias:

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

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

Rich Bradshaw
fuente
El enlace a la prueba estaba en "hice algunas pruebas" arriba. Lo haré más visible, pero aquí está de todos modos: jsfiddle.net/ZC3Lf
Hailwood
Encuentro una pregunta, si el atributo está personalizado, no las propiedades DOM, prop () devuelve undefinedy attr () funciona bien.
hiway
3

Hay un caso claro para ver las diferencias entre .prop y .attr

considere el HTML a continuación:

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

y el JS a continuación 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);
});

crea la siguiente salida:

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

He probado esto

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

y sale de la siguiente manera

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

esto puede indicar que actionse normaliza solo cuando se lee con prop.

Haocheng
fuente
No lo creo, ya que de lo contrario la salida 2)se normalizaría.
Hailwood
@Hailwood No lo hará, porque tienes /test/cuando el acceso a attr, y luego fijó /test/1a attr, que es attr del elemento. No hay ningún procedimiento que desencadene la normalización.
Haocheng
Estoy confundido en cuanto a lo que quiere decir, la prueba 2)anterior es element.attr(property, element.attr(property) + 1); body.append('Prop: '+element.prop(property)+'<br />'); body.append('Attr: '+element.attr(property)+'<hr />'); Si se normalizó cuando se leyó, ¿la línea final no generaría la versión normalizada?
Hailwood
Variables:property = 'action'; body = $('body'); element = $('form');
Hailwood
La normalización solo se activará cuando se acceda a prop , y el acceso de attr no.
Haocheng
1

ya que jquery 1.6.1+ attr () devuelve / cambia la propiedad como antes de 1.6. por lo tanto, sus pruebas no tienen mucho sentido.

tenga en cuenta los cambios menores en los valores de retorno.

p.ej

attr ('comprobado'): antes de 1.6 true / false es returend, desde 1.6.1. Se devuelve "comprobado" / indefinido.

attr ('selected'): antes de 1.6 se devuelve verdadero / falso, ya que 1.6.1 se devuelve "seleccionado" / indefinido

Aquí se puede encontrar una descripción detallada de este tema en alemán:

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

Martín Abraham
fuente