Pregunta .prop () versus .attr ()


Asi que jQuery 1.6 tiene la nueva función prop().

$(selector).click(function(){
    //instead of:
    this.getAttribute('style');
    //do i use:
    $(this).prop('style');
    //or:
    $(this).attr('style');
})

o en este caso, ¿hacen lo mismo?

Y si yo hacer tiene que cambiar a usar prop(), todo el viejo attr() las llamadas se romperán si cambio a 1.6?

ACTUALIZAR

selector = '#id'

$(selector).click(function() {
    //instead of:
    var getAtt = this.getAttribute('style');
    //do i use:
    var thisProp = $(this).prop('style');
    //or:
    var thisAttr = $(this).attr('style');

    console.log(getAtt, thisProp, thisAttr);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
<div id='id' style="color: red;background: orange;">test</div>

(Ver también este violín: http://jsfiddle.net/maniator/JpUF2/)

La consola registra el getAttribute como una cadena, y el attr como una cadena, pero el prop como un CSSStyleDeclaration, ¿Por qué? ¿Y cómo afecta eso mi codificación en el futuro?


2053
2018-05-03 19:33


origen


Respuestas:


Actualización 1 de noviembre de 2012

Mi respuesta original se aplica específicamente a jQuery 1.6. Mi consejo sigue siendo el mismo, pero jQuery 1.6.1 cambió ligeramente las cosas: ante la cantidad de sitios web rotos pronosticados, el equipo de jQuery revertido attr() a algo cercano a (pero no exactamente lo mismo que) su comportamiento anterior para atributos booleanos. John Resig también blogueó sobre eso. Puedo ver la dificultad en la que estaban pero aún no estoy de acuerdo con la recomendación de preferir attr().

Respuesta original

Si solo has usado jQuery y no el DOM directamente, esto podría ser un cambio confuso, aunque definitivamente es una mejora conceptual. No obstante, no es tan bueno para los millones de sitios que usan jQuery que se romperán como resultado de este cambio.

Resumiré los principales problemas:

  • Usualmente quieres prop() más bien que attr().
  • En la mayoría de los casos, prop() hace que attr() usado para hacer. Reemplazar llamadas a attr() con prop() en tu código generalmente funcionará.
  • Las propiedades son generalmente más simples de manejar que los atributos. Un valor de atributo solo puede ser una cadena mientras que una propiedad puede ser de cualquier tipo. Por ejemplo, el checked propiedad es un booleano, el style propiedad es un objeto con propiedades individuales para cada estilo, el size la propiedad es un número.
  • Cuando existen tanto una propiedad como un atributo con el mismo nombre, por lo general la actualización actualizará la otra, pero este no es el caso para ciertos atributos de entradas, tales como value y checked: para estos atributos, la propiedad siempre representa el estado actual mientras que el atributo (excepto en las versiones anteriores de IE) corresponde al valor predeterminado / verificación de la entrada (reflejado en el defaultValue / defaultChecked propiedad).
  • Este cambio elimina parte de la capa de jQuery mágico pegada al frente de los atributos y propiedades, lo que significa que los desarrolladores de jQuery tendrán que aprender un poco sobre la diferencia entre las propiedades y los atributos. Ésto es una cosa buena.

Si eres un desarrollador de jQuery y estás confundido por todo este asunto sobre propiedades y atributos, necesitas dar un paso atrás y aprender un poco sobre él, ya que jQuery ya no está tratando de protegerte de estas cosas. Para la palabra autorizada pero algo seca sobre el tema, están las especificaciones: DOM4, HTML DOM, Nivel DOM 2, Nivel DOM 3. La documentación de DOM de Mozilla es válida para la mayoría de los navegadores modernos y es más fácil de leer que las especificaciones, por lo que puede encontrar su Referencia DOM servicial. Hay una sección sobre las propiedades del elemento.

Como ejemplo de cómo las propiedades son más fáciles de manejar que los atributos, considere una casilla de verificación que se verifica inicialmente. Aquí hay dos posibles piezas de HTML válido para hacer esto:

<input id="cb" type="checkbox" checked>
<input id="cb" type="checkbox" checked="checked">

Entonces, ¿cómo averigua si la casilla de verificación está marcada con jQuery? Consulte Desbordamiento de pila y encontrará comúnmente las siguientes sugerencias:

  • if ( $("#cb").attr("checked") === true ) {...}
  • if ( $("#cb").attr("checked") == "checked" ) {...}
  • if ( $("#cb").is(":checked") ) {...}

Esto es realmente lo más simple del mundo para hacer con el checked Propiedad booleana, que ha existido y funcionado a la perfección en todos los principales navegadores de secuencias de comandos desde 1995:

if (document.getElementById("cb").checked) {...}

La propiedad también hace que marcar o desmarcar la casilla de verificación sea trivial:

document.getElementById("cb").checked = false

En jQuery 1.6, esto se convierte sin ambigüedades

$("#cb").prop("checked", false)

La idea de usar el checked atributo para la creación de scripts de una casilla de verificación no es útil e innecesario. La propiedad es lo que necesitas.

  • No es obvio cuál es la forma correcta de marcar o desmarcar la casilla de verificación checked atributo
  • El valor del atributo refleja el estado predeterminado en lugar del visible actual (excepto en algunas versiones anteriores de IE, lo que hace que las cosas sigan siendo más difíciles). El atributo no le dice nada sobre si la casilla de verificación de la página está marcada. Ver http://jsfiddle.net/VktA6/49/.

1734
2018-05-03 23:06



creo Tim lo dijo bastante bien, pero retrocedamos:

Un elemento DOM es un objeto, una cosa en la memoria. Como la mayoría de los objetos en OOP, tiene propiedades. También, por separado, tiene un mapa de los atributos definidos en el elemento (por lo general, proviene del marcado que el navegador leyó para crear el elemento). Algunos de los elementos propiedades conseguir su inicial valores de atributos con nombres iguales o similares (value obtiene su valor inicial del atributo "valor"; href obtiene su valor inicial del atributo "href", pero no es exactamente el mismo valor; className del atributo "clase"). Otras propiedades obtienen sus valores iniciales de otras maneras: por ejemplo, el parentNode la propiedad obtiene su valor en función de cuál es su elemento padre; un elemento siempre tiene una style propiedad, si tiene un atributo de "estilo" o no.

Consideremos este ancla en una página en http://example.com/testing.html:

<a href='foo.html' class='test one' name='fooAnchor' id='fooAnchor'>Hi</a>

Un poco de arte ASCII gratuito (y dejando de lado un montón de cosas):

+ ------------------------------------------- +
| HTMLAnchorElement |
+ ------------------------------------------- +
| href: "http://example.com/foo.html" |
| nombre: "fooAnchor" |
| id: "fooAnchor" |
| className: "prueba uno" |
| atributos: |
| href: "foo.html" |
| nombre: "fooAnchor" |
| id: "fooAnchor" |
| clase: "prueba uno" |
+ ------------------------------------------- +

Tenga en cuenta que las propiedades y los atributos son distintos.

Ahora bien, aunque son distintos, debido a que todo esto evolucionó en lugar de diseñarse desde cero, varias propiedades escriben de nuevo el atributo del que derivaron si lo configuraste. Pero no todos lo hacen, y como pueden ver en hrefarriba, el mapeo no es siempre un "paso directo", a veces hay una interpretación involucrada.

Cuando hablo de que las propiedades son propiedades de un objeto, no estoy hablando en abstracto. Aquí hay un código que no es jQuery:

var link = document.getElementById('fooAnchor');
alert(link.href);                 // alerts "http://example.com/foo.html"
alert(link.getAttribute("href")); // alerts "foo.html"

(Esos valores son como la mayoría de los navegadores, hay algunas variaciones).

los link objeto es una cosa real, y se puede ver que hay una distinción real entre acceder a un propiedad en él, y acceder a un atributo.

Como dijo Tim, el amplia mayoría del tiempo, queremos trabajar con propiedades. En parte, eso se debe a que sus valores (incluso sus nombres) tienden a ser más consistentes en todos los navegadores. Principalmente, solo queremos trabajar con atributos cuando no hay ninguna propiedad relacionada con él (atributos personalizados), o cuando sabemos que para ese atributo en particular, el atributo y la propiedad no son 1: 1 (como con href y "href" arriba).

Las propiedades estándar se presentan en varias especificaciones DOM:

Estas especificaciones tienen índices excelentes y recomiendo mantener enlaces a mano; Los utilizo todo el tiempo.

Los atributos personalizados incluirían, por ejemplo, cualquier data-xyz atributos que podría poner en elementos para proporcionar metadatos a su código (ahora que es válido a partir de HTML5, siempre y cuando se adhiera a la data- prefijo). (Las versiones recientes de jQuery le dan acceso a data-xyz elementos a través de la data función, pero esa función es no solo un accesorio para data-xyz atributos [hace más y menos que eso]; a menos que realmente necesite sus características, usaría el attr función para interactuar con data-xyz atributo.)

los attr la función solía tener una lógica intrincada en torno a obtener lo que creían que quería, en lugar de obtener literalmente el atributo. Combinó los conceptos. Moviéndose a prop y attr estaba destinado a des-confundirlos. Brevemente en v1.6.0 jQuery fue demasiado lejos en ese sentido, pero la funcionalidad fue rápidamente agregado nuevamente a attr para manejar las situaciones comunes donde las personas usan attr cuando técnicamente deberían usar prop.


621
2018-05-04 14:27



Este cambio ha sido un largo tiempo para jQuery. Durante años, se han contentado con una función llamada attr() que en su mayoría recupera propiedades DOM, no el resultado que esperaría del nombre. La segregación de attr() y prop() debería ayudar a aliviar parte de la confusión entre los atributos HTML y las propiedades DOM. $.fn.prop() agarra la propiedad DOM especificada, mientras $.fn.attr() agarra el atributo HTML especificado.

Para entender completamente cómo funcionan, aquí hay una explicación extendida sobre la diferencia entre los atributos HTML y las propiedades DOM:

Atributos de HTML

Sintaxis:

<body onload="foo()">

Propósito: Permite que el marcado tenga datos asociados con él para eventos, procesamiento y otros fines.

Visualización: HTML AttributesEl atributo de clase se muestra aquí en el cuerpo. Se puede acceder a través del siguiente código:

var attr;
attr = document.body.getAttribute("class");
//IE 8 Quirks and below
attr = document.body.getAttribute("className");

Los atributos se devuelven en forma de cadena y pueden ser inconsistentes desde el navegador al navegador. Sin embargo, pueden ser vitales en algunas situaciones. Como se ejemplificó anteriormente, IE 8 Quirks Mode (y siguientes) espera el nombre de una propiedad DOM en get / set / removeAttribute en lugar del nombre del atributo. Esta es una de las muchas razones por las cuales es importante saber la diferencia.

DOM Properties

Sintaxis:

document.body.onload = foo;

Propósito: Da acceso a las propiedades que pertenecen a los nodos de elementos. Estas propiedades son similares a los atributos, pero solo son accesibles a través de JavaScript. Esta es una diferencia importante que ayuda a aclarar el rol de las propiedades DOM. Tenga en cuenta que los atributos son completamente diferentes de las propiedades, ya que esta asignación de controlador de eventos es inútil y no recibirá el evento (el cuerpo no tiene un evento de carga, solo un atributo de carga).

Visualización: DOM Properties

Aquí, verás una lista de propiedades debajo de la pestaña "DOM" en Firebug. Estas son propiedades DOM. Inmediatamente notará bastantes de ellos, ya que los habrá usado antes sin saberlo. Sus valores son lo que recibirá a través de JavaScript.

Documentación

Ejemplo

HTML: <textarea id="test" value="foo"></textarea>

JavaScript: alert($('#test').attr('value'));

En versiones anteriores de jQuery, esto devuelve una cadena vacía. En 1.6, devuelve el valor correcto, foo.

Sin haber echado un vistazo al nuevo código para ninguna función, puedo decir con confianza que la confusión tiene más que ver con la diferencia entre los atributos HTML y las propiedades DOM que con el código en sí. Con suerte, esto despejó algunas cosas para usted.

-Mate


234
2018-05-03 20:05



Una propiedad está en el DOM; un atributo está en el HTML que se analiza en el DOM.

Más detalles

Si cambia un atributo, el cambio se reflejará en el DOM (a veces con un nombre diferente).

Ejemplo: cambiar el class atributo de una etiqueta cambiará el className propiedad de esa etiqueta en el DOM. Si no tiene ningún atributo en una etiqueta, todavía tiene la propiedad de DOM correspondiente con un valor vacío o predeterminado.

Ejemplo: mientras su etiqueta no tiene class atributo, la propiedad DOM className existe con un valor de cadena vacío.

editar

Si cambia el uno, el otro será cambiado por un controlador, y viceversa. Este controlador no está en jQuery, sino en el código nativo del navegador.


232
2017-09-27 16:55



Es solo la distinción entre atributos HTML y objetos DOM lo que causa confusión. Para aquellos que se sienten cómodos actuando sobre las propiedades nativas de los elementos DOM como this.src  this.value  this.checked etc, .prop es una muy cálida bienvenida a la familia. Para otros, es solo una capa adicional de confusión. Vamos a aclarar eso.

La forma más fácil de ver la diferencia entre .attr y .prop es el siguiente ejemplo:

<input blah="hello">
  1. $('input').attr('blah'): devoluciones 'hello'como se esperaba. No hay sorpresas aquí.
  2. $('input').prop('blah'): devoluciones undefined - porque está tratando de hacer [HTMLInputElement].blah - y no existe tal propiedad en ese objeto DOM. Solo existe en el alcance como un atributo de ese elemento, es decir [HTMLInputElement].getAttribute('blah')

Ahora cambiamos algunas cosas así:

$('input').attr('blah', 'apple');
$('input').prop('blah', 'pear');
  1. $('input').attr('blah'): devoluciones 'apple' ¿eh? ¿Por qué no "pera", ya que se estableció por última vez en ese elemento. Debido a que la propiedad se modificó en el atributo de entrada, no el elemento de entrada DOM en sí mismo, básicamente casi funcionan de forma independiente el uno del otro.
  2. $('input').prop('blah'): devoluciones 'pear'

Lo que realmente necesita tener cuidado es solo no mezcle el uso de estos para la misma propiedad en toda su aplicación por la razón anterior.

Vea un violín que demuestra la diferencia:  http://jsfiddle.net/garreh/uLQXc/


.attr vs .prop:

Ronda 1: estilo

<input style="font:arial;"/>
  • .attr('style') - devuelve estilos en línea para el elemento coincidente, es decir "font:arial;"
  • .prop('style') - devuelve un objeto de declaración de estilo, es decir CSSStyleDeclaration

Ronda 2: valor

<input value="hello" type="text"/>   

$('input').prop('value', 'i changed the value');
  • .attr('value') -- devoluciones 'hello' *
  • .prop('value') -- devoluciones 'i changed the value'

* Nota: jQuery por este motivo tiene una .val() método, que internamente es equivalente a .prop('value')


131
2018-05-19 10:18



TL; DR

Utilizar prop() encima attr() en la mayoría de los casos.

UN propiedad es el estado actual del elemento de entrada. Un atributo es el valor predeterminado.

Una propiedad puede contener cosas de diferentes tipos. Un atributo solo puede contener cadenas


48
2017-07-16 09:45



Dirty Checkness

Este concepto es un ejemplo donde la diferencia es observable: http://www.w3.org/TR/html5/forms.html#concept-input-checked-dirty

Pruébalo:

  • clic en el botón. Ambas casillas de verificación fueron verificadas.
  • desmarque ambas casillas de verificación.
  • haga clic en el botón nuevamente Solo el prop la casilla de verificación se comprobó. ¡EXPLOSIÓN!

$('button').on('click', function() {
  $('#attr').attr('checked', 'checked')
  $('#prop').prop('checked', true)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label>attr <input id="attr" type="checkbox"></label>
<label>prop <input id="prop" type="checkbox"></label>
<button type="button">Set checked attr and prop.</button>

Para algunos atributos como disabled en button, agregar o eliminar el atributo de contenido disabled="disabled" siempre alterna la propiedad (llamada atributo IDL en HTML5) porque http://www.w3.org/TR/html5/forms.html#attr-fe-disabled dice:

El atributo IDL deshabilitado debe reflejar el atributo de contenido deshabilitado.

por lo que puede salirse con la suya, aunque es feo, ya que modifica HTML sin necesidad.

Para otros atributos como checked="checked" en input type="checkbox", las cosas se rompen, porque una vez que hace clic en él, se ensucia, y luego agrega o quita el checked="checked" atributo de contenido ya no bloquea la verificación.

Esta es la razón por la cual debes usar principalmente .prop, ya que afecta la propiedad efectiva directamente, en lugar de depender de efectos secundarios complejos.


34
2017-07-06 11:43



Todo está en el documento:

La diferencia entre atributos y propiedades puede ser importante en situaciones específicas. Antes de jQuery 1.6, el método .attr () a veces tomaba en cuenta los valores de propiedades al recuperar algunos atributos, lo que podía causar un comportamiento incoherente. A partir de jQuery 1.6, el método .prop () proporciona una forma de recuperar explícitamente valores de propiedad, mientras que .attr () solo recupera atributos.

¡Entonces usa prop!


32
2018-05-03 19:35



atributos están en tu HTML documento / archivo de texto (== imagine que este es el resultado de su etiqueta HTML analizada), mientras que
propiedadesestán en HTML Árbol DOM (== básicamente una propiedad real de algún objeto en el sentido JS).

Es importante destacar que muchos de ellos están sincronizados (si actualiza class propiedad, class el atributo en html también se actualizará; y de lo contrario). Pero algunos atributos se pueden sincronizar con propiedades inesperadas, por ejemplo, atributo  checked corresponde a propiedad  defaultChecked, así que eso

  • marcar manualmente una casilla de verificación cambiará .prop('checked') valor, pero no cambiará .attr('checked') y .prop('defaultChecked') valores
  • ajuste $('#input').prop('defaultChecked', true) también cambiará .attr('checked'), pero esto no será visible en un elemento.

La regla de oro es: .prop() El método debe usarse para propiedades / atributos booleanos y para propiedades que no existen en html   (como window.location). Todos los otros atributos (los que puedes ver en   el html) puede y debe continuar siendo manipulado con el .attr()   método. (http://blog.jquery.com/2011/05/10/jquery-1-6-1-rc-1-released/)

Y aquí hay una tabla que muestra dónde .prop() es preferido (aunque .attr() todavía se puede usar).

  table with preferred usage


¿Por qué a veces querrías usar .prop () en lugar de .attr () donde último es oficialmente asesorado?

  1. .prop() puede devolver cualquier tipo - cadena, entero, booleano; mientras .attr() siempre devuelve una cadena.
  2. .prop() se dice que es aproximadamente 2.5 veces más rápido que .attr().

26
2018-06-12 05:56



.attr():

  • Obtenga el valor de un atributo para el primer elemento en el conjunto de elementos combinados.
  • Te da el valor del elemento como se definía en el html en la carga de la página

.prop():

  • Obtenga el valor de un propiedad para el primer elemento en el conjunto de elementos combinados.
  • Da los valores actualizados de los elementos que se modifican mediante javascript / jquery

18
2017-12-08 09:14



Por lo general, querrás usar propiedades. Use atributos solo para:

  1. Obtener un atributo HTML personalizado (ya que no está sincronizado con una propiedad DOM).
  2. Obteniendo un atributo HTML que no se sincroniza con una propiedad DOM, p. obtener el "valor original" de un atributo HTML estándar, como <input value="abc">.

13
2018-02-02 20:36