.prop () vs .attr ()

Así que jQuery 1.6 tiene una 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 necesito cambiar a usar prop() , ¿se interrumpirán todas las llamadas attr() si cambio a 1.6?

ACTUALIZACIÓN

 <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> 

(Véase también este script: http://jsfiddle.net/maniator/JpUF2/ )

La consola registra getAttribute como una cadena, y attr - como una cadena, pero prop como CSSStyleDeclaration , ¿por qué? ¿Y cómo afectará esto a mi codificación en el futuro?

2141
03 мая '11 в 22:33 2011-05-03 22:33 Neal se estableció el 3 de mayo de 2011 a las 10:33 del 2011-05-03 22:33
@ 18 respuestas

Actualización 1 de noviembre de 2012

Mi respuesta inicial se relaciona específicamente con jQuery 1.6. Mi consejo sigue siendo el mismo, pero jQuery 1.6.1 cambió ligeramente la situación: ante el montón previsto de sitios web rotos, el equipo de jQuery devolvió attr() a algo cercano (pero no exactamente el mismo) a su antiguo comportamiento para los atributos lógicos , John Resig también informó de esto en un blog . Veo las dificultades que enfrentan, pero aún no estoy de acuerdo con su recomendación de preferir attr() .

Respuesta original

Si solo ha usado jQuery, y no DOM directamente, esto puede ser un cambio confuso, aunque ciertamente mejora conceptualmente. No tan bueno para los bazillones de sitios jQuery que se rompen como resultado de este cambio.

Resumiré los principales temas:

  • Por lo general, necesitas prop() y no attr() .
  • En la mayoría de los casos, prop() hace lo que attr() hizo antes. Reemplazar llamadas attr() con prop() en su código generalmente funcionará.
  • Las propiedades suelen ser más fáciles de tratar con los atributos. Un valor de atributo solo puede ser una cadena, mientras que una propiedad puede ser de cualquier tipo. Por ejemplo, la propiedad checked es una propiedad lógica, la propiedad de style es un objeto con propiedades individuales para cada estilo, la propiedad de size es un número.
  • Donde hay una propiedad y un atributo con el mismo nombre, generalmente la actualización de una actualizará la otra, pero esto no se aplica a algunos atributos de los datos de entrada, como el value y la checked : para estos atributos, la propiedad siempre representa el estado actual mientras que el atributo (para Con la excepción de las versiones anteriores de IE, corresponde al valor / validación de la entrada predeterminada (reflejada en defaultChecked / defaultChecked ).
  • Este cambio elimina alguna capa de magia jQuery, pegada frente a atributos y propiedades, lo que significa que los desarrolladores de jQuery tendrán que aprender un poco sobre la diferencia entre propiedades y atributos. Esto es algo bueno.

Si usted es un desarrollador de jQuery y está confundido acerca de las propiedades y los atributos en este negocio, necesita retroceder un poco y aprender un poco sobre esto, porque jQuery ya no está tratando de protegerlo tanto de esto. Para las personas con autoridad, pero algunas palabras reales sobre este tema hay especificaciones: DOM4 , HTML DOM , DOM Nivel 2 , DOM Nivel 3 . La documentación de Mozilla DOM 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 información de referencia de DOM . Hay una sección sobre las propiedades del elemento .

Como ejemplo de cómo las propiedades son más fáciles de procesar que los atributos, considere la casilla de verificación que se marcó originalmente. Aquí hay dos partes posibles de HTML válido:

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

Entonces, ¿cómo sabes si la casilla de verificación se establece con jQuery? Mira el desbordamiento de pila y normalmente encontrarás las siguientes oraciones:

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

De hecho, esta es la cosa más simple del mundo que está asociada con una propiedad booleana checked que ha existido y ha funcionado perfectamente en todos los navegadores principales con la capacidad de ver desde 1995:

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

La propiedad también hace que la verificación o el borrado de una bandera sea trivial:

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

En jQuery 1.6, esto definitivamente se convierte en

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

La idea de usar el atributo checked para una casilla de verificación de script es inútil e innecesaria. La propiedad es lo que necesitas.

  • No está claro cuál es la forma correcta de marcar o desmarcar una marca con el atributo checked
  • El valor del atributo refleja el valor predeterminado, no el estado visible actual (con la excepción de algunas versiones anteriores de IE, lo que complica aún más las cosas). El atributo no indica si la casilla de verificación está marcada en la página. Ver http://jsfiddle.net/VktA6/49/ .
1790
04 мая '11 в 2:06 2011-05-04 02:06 Tim Down dio la respuesta el 4 de mayo de 2011 a las 2:06 2011-05-04 02:06

Creo que Tim lo dijo bastante bien , pero lo dejó retroceder:

El elemento DOM es un objeto, un elemento en la memoria. Como la mayoría de los objetos en OOP, tiene propiedades. También, por separado, tiene un mapa de atributos definido en el elemento (generalmente proviene del marcado que el navegador lee para crear el elemento). Algunas de las propiedades de un elemento obtienen sus valores iniciales de atributos con el mismo nombre o similar (el value obtiene su valor inicial del atributo "valor"; href obtiene su valor inicial del atributo "href", pero este no es exactamente el mismo valor; className del atributo " clase "). Otras propiedades obtienen sus valores iniciales de otras maneras: por ejemplo, la propiedad parentNode obtiene su valor en función de su elemento principal; un elemento siempre tiene una propiedad de style , tenga o no un atributo de style .

Considere este ancla en la 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 muchas 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 atributos son diferentes.

Ahora, aunque son diferentes, ya que todo esto se desarrolla, y no se desarrolla desde cero, una serie de propiedades se vuelven a escribir en el atributo del cual se obtuvieron, si las configura. Pero no todos lo hacen, y, como puede ver en el href anterior, el mapeo no siempre es directo para "transmitir el significado", a veces se usa la interpretación.

Cuando hablo de propiedades que son propiedades de un objeto, no hablo de manera abstracta. Aquí hay un código que no es jQuery:

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

(Estos valores corresponden a la mayoría de los navegadores, hay algunas opciones).

El objeto de link es lo real, y puedes ver que hay una diferencia real entre acceder a él y acceder a él.

Como dijo Tim, la gran mayoría de ese tiempo, queremos trabajar con propiedades. Esto se debe en parte a que sus valores (incluso sus nombres) suelen ser más consistentes entre los navegadores. Principalmente queremos trabajar solo con atributos cuando no hay una propiedad asociada (atributos de usuario), o cuando sabemos que para este atributo en particular, el atributo y la propiedad no son 1: 1 (como en href y "href" más arriba).

Las propiedades estándar se establecen en varias especificaciones de DOM:

Estas especificaciones tienen índices excelentes y recomiendo que sean cómodos de usar; Los uso todo el tiempo.

Los atributos personalizados incluyen, por ejemplo, cualquier atributo data-xyz que podría poner en elementos para proporcionar metadatos a su código (ahora esto es válido con HTML5, si sigue el prefijo de data- ), (las últimas versiones de jQuery le dan acceso a data-xyz usando la función data , pero esta función no es solo para los accesorios para data-xyz atributos de data-xyz [hace esto y mucho más que eso], si realmente no necesita sus funciones, usaría la función attr para interactuar con el atributo data-xyz .)

La función attr usó cierta lógica confusa para obtener lo que pensaban que querías, en lugar de obtener literalmente el atributo. Combinó el concepto. Moverse a prop y attr pensado para su desconfiguración. Brevemente, en v1.6.0, jQuery fue demasiado lejos en este sentido, pero la funcionalidad se agregó rápidamente al attr para manejar situaciones comunes en las que las personas usan attr cuando técnicamente deberían usar prop .

639
04 мая '11 в 17:27 2011-05-04 17:27 La respuesta es dada por TJ Crowder el 4 de mayo de 2011 a las 5:27 pm 2011-05-04 17:27

Este cambio se produjo hace mucho tiempo para jQuery. Durante años, han estado satisfechos con una función llamada attr() que básicamente recuperó las propiedades del DOM, en lugar del resultado que se espera del nombre. La segregación de attr() y prop() debería ayudar a mitigar la confusión entre los atributos HTML y las propiedades DOM. $.fn.prop() captura la propiedad DOM especificada, y $.fn.attr() captura el atributo HTML especificado.

Para comprender completamente cómo funcionan, aquí hay una explicación extensa de las diferencias entre los atributos HTML y las propiedades DOM.

Atributos HTML

Sintaxis:

<body onload="foo()">

Propósito: permite que el marcado tenga datos asociados para eventos, renderización y otros propósitos.

Visualización: 2019

242
03 мая '11 в 23:05 2011-05-03 23:05 la respuesta la da el usuario 1385191 03 de mayo de 2011 a las 23:05 2011-05-03 23:05

La propiedad está en el DOM; El atributo está en HTML, que se analiza en el DOM.

Información adicional

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

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

Un ejemplo Aunque su etiqueta no tiene ningún atributo de class , la propiedad DOM className existe con un valor de cadena vacío.

cambiar

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

237
27 сент. respuesta dada yunzen sep 27 2011-09-27 19:55 '11 a las 19:55 2011-09-27 19:55

Es la diferencia entre los atributos HTML y los objetos DOM confusos. Para aquellos que se sienten cómodos con las propiedades de las propiedades DOM, como this.src this.value this.checked , etc., .prop es una bienvenida muy cálida en la familia. Para otros, esto es solo una confusión adicional. Que quede claro.

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

 <input blah="hello"> 
  • $('input').attr('blah') : devuelve 'hello' , como se esperaba. No hay sorpresas.
  • $('input').prop('blah') : devuelve undefined , porque está intentando hacer [HTMLInputElement].blah , y no hay tal propiedad en este objeto DOM. Solo existe en el dominio como un atributo de este elemento, es decir, [HTMLInputElement].getAttribute('blah')

Ahora cambiamos algunas cosas como esta:

 $('input').attr('blah', 'apple'); $('input').prop('blah', 'pear'); 
  • $('input').attr('blah') : devuelve 'apple' eh? ¿Por qué no "pera" porque fue el último para este elemento. Debido a que la propiedad se ha cambiado a un atributo de entrada y no a un elemento de entrada DOM, básicamente funcionan de forma casi independiente entre sí.
  • $('input').prop('blah') : devuelve 'pear'

Lo que realmente debe tener cuidado es simplemente no mezclar el uso de este para la misma propiedad en toda la aplicación por la razón anterior.

Vea el violín que muestra 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 el objeto de declaración de estilo, es decir, CSSStyleDeclaration

Ronda 2: significado

 <input value="hello" type="text"/> $('input').prop('value', 'i changed the value'); 
  • .attr('value') - devuelve 'hello' *
  • .prop('value') - devuelve 'i changed the value'

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

134
19 мая '11 в 13:18 2011-05-19 13:18 la respuesta la da Gary Green el 19 de mayo de 2011 a las 13:18 2011-05-19 13:18

Tl; DR

Use prop() sobre attr() en la mayoría de los casos.

La propiedad es el estado actual del elemento de entrada. Atributo es el valor predeterminado.

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

49
16 июля '14 в 12:45 2014-07-16 12:45 la respuesta está dada por agjmills 16 de julio de 2014 a las 12:45 2014-07-16 12:45

Cheque sucio

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

Prueba

  • Haga clic en el botón. Ambas casillas fueron marcadas.
  • desmarque ambas casillas.
  • Presiona el botón otra vez. Sólo se prop bandera de prop . Bang

 <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 un button , agregar o eliminar el atributo de contenido está disabled="disabled" siempre alterna una 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 del contenido deshabilitado.

para que puedas alejarte de él, aunque sea feo, ya que cambia el HTML innecesariamente.

Para otros atributos, tales como checked="checked" en input type="checkbox" , todo se descompone, porque tan pronto como se hace clic en él, se ensucia, y luego se agrega o elimina el atributo " checked="checked" para cancelar la verificación .

Es por eso que debería usar principalmente .prop , porque afecta directamente la propiedad efectiva, en lugar de confiar en los complejos efectos secundarios de la modificación de HTML.

35
06 июля '14 в 14:43 2014-07-06 14:43 Respuesta dada por Ciro Santilli 改造 中心 六四 事件 法轮功 Julio 06 '14 a las 14:43 2014-07-06 14:43

Todo el muelle :

La diferencia entre atributos y propiedades puede ser importante en ciertas situaciones. Antes de jQuery 1.6, el método .attr () a veces tomaba en cuenta los valores de las propiedades al extraer ciertos atributos, lo que podría causar un comportamiento inconsistente. A partir de jQuery 1.6, el método .prop () proporciona una forma de obtener valores de propiedad explícitamente, mientras que .attr () devuelve atributos.

¡Así que usa un pilar!

32
03 мая '11 в 22:35 2011-05-03 22:35 Arnaud F. dio la respuesta el 3 de mayo de 2011 a las 10:35 2011-05-03 22:35

los atributos están en su documento de texto / archivo HTML (== imagina que esto es el resultado de analizar el marcado del marcado html), mientras que las propiedades están en el árbol HTML DOM (== básicamente la propiedad real de algún objeto en el sentido de JS).

Es importante tener en cuenta que muchos de ellos están sincronizados (si actualiza la propiedad de class , y el atributo de class en html también se actualizará, pero de lo contrario). Sin embargo, algunos atributos se pueden sincronizar con propiedades inesperadas, por ejemplo, el atributo checked corresponde a la propiedad defaultChecked , por lo que

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

La regla del pulgar : el método .prop() debe usarse para atributos / propiedades lógicas y para propiedades que no existen en html (por ejemplo, window.location). Todos los demás atributos (que puede ver en html) pueden y deben seguir siendo manipulados utilizando el método .attr() . ( http://blog.jquery.com/2011/05/10/jquery-1-6-1-rc-1-released/ )

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

2019

26
12 июня '15 в 8:56 2015-06-12 08:56 la respuesta es dada por lakesare el 12 de junio de '15 a las 8:56 2015-06-12 08:56

.attr() :

  • Obtener valor de atributo para el primer elemento en el conjunto de elementos emparejados.
  • Le da el valor del elemento tal como se define en el html en la carga de la página.

.prop() :

  • Obtener valor de la propiedad para el primer elemento en el conjunto de elementos emparejados.
  • Da valores actualizados de elementos que se modifican usando javascript / jquery
18
08 дек. La respuesta se da Kgn-web 08 dec. 2015-12-08 12:14 '15 a las 12:14 2015-12-08 12:14

Normalmente quieres usar propiedades. Use atributos solo para:

  • Obtención de atributos HTML personalizados (porque no está sincronizado con la propiedad DOM).
  • Obtención de un atributo HTML que no se sincroniza con la propiedad DOM, por ejemplo. obtenga el "valor original" del atributo HTML estándar, por ejemplo <input value="abc">.
13
02 февр. la respuesta se da naor 02 feb. 2014-02-02 23:36 '14 a las 11:36 pm 2014-02-02 23:36

attributes → HTML

properties → DOM

7
26 дек. La respuesta se da NkS 26 de diciembre. 2014-12-26 16:28 '14 a las 16:28 2014-12-26 16:28

Antes de jQuery 1.6, el método attr() veces tenía en cuenta los valores de las propiedades al extraer atributos, lo que provocaba un comportamiento bastante contradictorio.

La introducción del método prop() proporciona una manera de recuperar explícitamente valores de propiedades, mientras que .attr() extrae atributos.

Documentos:

jQuery.attr() Obtiene el valor de atributo para el primer elemento en el conjunto de elementos coincidentes.

jQuery.prop() Obtiene el valor de propiedad para el primer elemento en el conjunto de elementos coincidentes.

6
25 окт. Respuesta dada por Gothburz el 25 de octubre. 2015-10-25 03:05 '15 a las 3:05 2015-10-25 03:05

Recuérdanos cuidadosamente de usar prop() , por ejemplo:

 if ($("#checkbox1").prop('checked')) { isDelete = 1; } else { isDelete = 0; }