.prop () vs .attr ()

2301

Entonces 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 no debe de cambiar a usar prop(), todas las viejas attr()llamadas se romperá si me 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>

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

La consola registra el getAttributecomo una cadena y el attrcomo una cadena, pero el propcomo un CSSStyleDeclaration, ¿Por qué? ¿Y cómo afecta eso a mi codificación en el futuro?

Naftali aka Neal
fuente
17
Esto será de gran interés: books.google.ca/…
28
@Neal, es porque este cambio trasciende jQuery. La diferencia entre los atributos HTML y las propiedades DOM es enorme.
77
Me entristece ver que jQuery ha revertido los cambios. Se dirigen en la dirección equivocada.
44
@Neal. Sí, y simplemente complica aún más el problema en lugar de separar los dos métodos.
66
@BritishDeveloper la respuesta es más complicada que simplemente decir que siempre use x o y porque depende de lo que pretenda obtener. ¿Quieres el atributo o quieres la propiedad? Son dos cosas muy diferentes.
Kevin B

Respuestas:

1876

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ó un poco las cosas: frente a la pila de sitios web dañados, el equipo de jQuery volvió attr()a algo cercano (pero no exactamente igual) a su antiguo comportamiento para los atributos booleanos . John Resig también escribió en su blog al respecto . Puedo ver la dificultad en la que estaban pero aún no estoy de acuerdo con su recomendación de preferir attr().

Respuesta original

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

Resumiré los principales problemas:

  • Usualmente quieres prop()más que attr().
  • En la mayoría de los casos, prop()hace lo que attr()solía hacer. Reemplazar llamadas attr()con prop()en su código generalmente funcionará.
  • Las propiedades son generalmente más simples de tratar que los atributos. Un valor de atributo solo puede ser una cadena, mientras que una propiedad puede ser de cualquier tipo. Por ejemplo, la checkedpropiedad es un booleano, la stylepropiedad es un objeto con propiedades individuales para cada estilo, la sizepropiedad es un número.
  • Cuando existe una propiedad y un atributo con el mismo nombre, generalmente actualizar uno actualizará el otro, pero este no es el caso para ciertos atributos de entradas, como valuey checked: para estos atributos, la propiedad siempre representa el estado actual mientras que el El atributo (excepto en versiones anteriores de IE) corresponde al valor predeterminado / verificación de la entrada (reflejado en la propiedad defaultValue/ defaultChecked).
  • Este cambio elimina parte de la capa de magia jQuery atrapada 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. Ésto es una cosa buena.

Si usted es un desarrollador de jQuery y está confundido por todo este negocio acerca de las propiedades y los atributos, debe dar un paso atrás y aprender un poco al respecto, ya que jQuery ya no está tratando tan duro de protegerlo de estas cosas. Para la palabra autorizada pero algo seca sobre el tema, están las especificaciones: DOM4 , HTML DOM , DOM Nivel 2 , DOM Nivel 3 . La documentación 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 útil su referencia DOM . Hay una sección sobre propiedades de elementos .

Como un ejemplo de cómo las propiedades son más fáciles de manejar que los atributos, considere una casilla de verificación que está marcada 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 saber si la casilla de verificación está marcada con jQuery? Mire en Stack Overflow y comúnmente encontrará las siguientes sugerencias:

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

En realidad, esto es lo más simple que se puede hacer en el mundo con la checkedpropiedad booleana, que ha existido y funcionó perfectamente en todos los principales navegadores programables desde 1995:

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

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

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

En jQuery 1.6, esto se convierte inequívocamente

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

La idea de usar el checkedatributo para escribir una casilla de verificación es inú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 utilizando el checkedatributo
  • El valor del atributo refleja el estado predeterminado en lugar del estado visible actual (excepto en algunas versiones anteriores de IE, lo que dificulta aún más las cosas). El atributo no le dice nada sobre si la casilla de verificación en la página está marcada. Ver http://jsfiddle.net/VktA6/49/ .
Tim Down
fuente
2
@TJCrowder, ¿cuáles?
Naftali aka Neal
99
@Neal: si desea saber qué propiedades tienen los elementos DOM y cómo los atributos pueden sembrar sus valores, tenga a mano estos enlaces: la especificación HTML DOM2 , la especificación DOM2 y la especificación DOM3 . Los índices en cada caso son excelentes y lo vinculan directamente a una descripción detallada de la propiedad, de dónde proviene su valor, etc.
TJ Crowder
44
@Neal: Re lo que lo hace diferente: la fuente y la naturaleza de la información. Mira el valueejemplo de Tim , por ejemplo. Una función llamada attrque recupera la propiedad en value lugar del atributo "valor" no tiene mucho sentido (y pueden ser diferentes). En el futuro, attrhacer atributos y prophacer propiedades será más claro, aunque la transición será dolorosa para algunos. No tome esto de la manera incorrecta, no hay nada como retroceder y leer las especificaciones para tener una idea de qué propiedades son.
TJ Crowder
54
@Neal: un elemento DOM es un objeto. Las propiedades son propiedades de ese objeto, al igual que cualquier otro objeto de programación. Algunos de esos accesorios obtienen sus valores iniciales de los atributos en el marcado, que también se almacenan en el objeto DOM en un mapa separado de atributos. En la mayoría de los casos, escribir en un accesorio solo cambia el accesorio, aunque lamentablemente hay algunos accesorios que escriben cualquier cambio en el atributo subyacente ( valuepor ejemplo), pero tratemos de ignorarlo. El 99% del tiempo, quieres trabajar con accesorios. Si necesita trabajar con un atributo real, probablemente lo sabrá.
TJ Crowder
44
@Tim: "Cambiar la valuepropiedad de una entrada no cambia su valueatributo en los navegadores modernos" No pensé que lo hiciera, por eso comencé a usarlo como ejemplo, pero cuando comencé a codificar el ejemplo, maldita sea si no se actualizó en Chrome, Firefox, Opera, IE ... - jsbin.com/ahire4 Resulta que era porque estaba usando un input[type="button"]para mi experimento. Que no actualiza el atributo en un input[type="text"]- jsbin.com/ahire4/2 Hablar de contorneado !! No solo el elemento, sino su tipo ...
TJ Crowder
664

Creo que 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 (generalmente proviene del marcado que el navegador leyó para crear el elemento). Algunas de las propiedades del elemento obtienen sus valores iniciales de atributos con el mismo nombre o nombres similares ( valueobtiene su valor inicial del atributo "valor"; hrefobtiene su valor inicial del atributo "href", pero no es exactamente el mismo valor; classNamedel atributo "clase"). Otras propiedades obtienen sus valores iniciales de otras maneras: por ejemplo, la parentNodepropiedad obtiene su valor en función de cuál es su elemento padre;style propiedad, tenga o no un atributo "estilo".

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 muchas cosas):

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

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

Ahora, aunque son distintos, debido a que todo esto evolucionó en lugar de ser diseñado desde cero, una serie de propiedades reescriben el atributo derivado si las configura. Pero no todos lo hacen, y como puede ver desde hrefarriba, el mapeo no siempre es un simple "pasar el valor", a veces hay interpretación involucrada.

Cuando hablo de propiedades como 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 según la mayoría de los navegadores; hay alguna variación).

El linkobjeto es algo real, y puede ver que hay una distinción real entre acceder a una propiedad y acceder a un atributo .

Como dijo Tim, la gran mayoría de las veces, queremos trabajar con propiedades. Esto se debe en parte 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 hrefy "href" arriba) .

Las propiedades estándar se presentan en las diversas especificaciones DOM:

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

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

La attrfunción solía tener una lógica complicada para obtener lo que pensaban que querías, en lugar de obtener literalmente el atributo. Combinó los conceptos. Mudarse a propy attrestaba destinado a desinflarlos. Brevemente en v1.6.0 jQuery fue demasiado lejos en ese sentido, pero la funcionalidad se añadió rápidamente volver a attrmanejar las situaciones comunes donde la gente utiliza attrcuando técnicamente se deben utilizar prop.

TJ Crowder
fuente
Guau. esa nueva actualización 1.6.1 realmente anula un poco esta pregunta ... (pero no mucho), pero ese enlace básicamente la responde ahora
Naftali, también conocido como Neal,
No lo anuló para mí, solo arreglé un error usando jquery1.7 donde estaba configurando .attr ('class', 'bla') y no funcionaba donde .prop ('className', 'bla' ) funcionó
PandaWood
@PandaWood: .attr('class', 'bla')funciona como se esperaba para mí en 1.7.0 , 1.7.1 y 1.7.2 en Chrome 17, Firefox 11, Opera 11, IE6, IE8, IE9 y Safari 5.
TJ Crowder
Gracias, debe haber algo específico en mi caso, déjenme verificar esto y volver con un caso de prueba. Pero cambiar el código como lo tenemos en este momento, simplemente "prop / className", en lugar de "attr" corrige un error masivo para nosotros que golpeó cuando pasamos de jquery1.4 a 1.7 - en todos los navegadores
PandaWood
3
@TJCrowder re: .data- leerá el valor predeterminado del atributo, si está presente, pero si le escribe, cambiará una propiedad oculta del elemento y no actualizará el atributo.
Alnitak
250

Este cambio ha tardado mucho en llegar a jQuery. Durante años, se han contentado con una función llamada attr()que recuperó principalmente las propiedades DOM, no el resultado que esperarías 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()toma la propiedad DOM especificada, mientras que $.fn.attr()toma el atributo HTML especificado.

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

Atributos HTML

Sintaxis:

<body onload="foo()">

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

Visualización: Atributos HTML el atributo de clase se muestra aquí en el cuerpo. Es accesible 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 de un navegador a otro. Sin embargo, pueden ser vitales en algunas situaciones. Como se ejemplificó anteriormente, IE 8 Quirks Mode (y a continuación) 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 que es importante saber la diferencia.

Propiedades DOM

Sintaxis:

document.body.onload = foo;

Propósito: Da acceso a propiedades que pertenecen a 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 papel 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: Propiedades DOM

Aquí, verá una lista de propiedades en la pestaña "DOM" en Firebug. Estas son propiedades DOM. Inmediatamente notará algunos de ellos, ya que los habrá usado antes sin saberlo. Sus valores son los 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 apropiado, foo.

Sin haber visto el nuevo código para ninguna de las funciones, 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 te aclaró algunas cosas.

-Mate

K.Dᴀᴠɪs
fuente
77
$.prop()obtiene propiedades DOM, $.attr()obtiene atributos HTML. Estoy tratando de cerrar la brecha psicológicamente para que puedas entender la diferencia entre los dos.
10
Chico, ahora estoy confundido también. ¿Entonces $('#test').prop('value')no devuelve nada? ¿Tampoco .attr('checked')para una casilla de verificación? Pero solía? ¿Ahora tendrías que cambiarlo prop('checked')? No entiendo la necesidad de esta distinción: ¿por qué es importante diferenciar entre los atributos HTML y las propiedades DOM? ¿Cuál es el caso de uso común que hizo que este cambio "tardara mucho en llegar" ? ¿Qué tiene de malo abstraer la distinción entre los dos, ya que parece que sus casos de uso se superponen principalmente?
BlueRaja - Danny Pflughoeft
55
@BlueRaja: porque hay una seria diferencia subyacente entre los dos conceptos que, si lo cepillas debajo de la alfombra como solía hacerlo jQuery, da lugar a fallas inesperadas. valuees uno de los casos más obvios, ya que la valuepropiedad le dará el valor actual de un campo, pero el valueatributo le dará el valor original que se declaró en el value="..."atributo, que en realidad es la defaultValuepropiedad. (Aunque este caso en particular se confunde de nuevo por errores en IE <9.)
bobince
44
@BlueRaja: La respuesta a eso es aún más complicada. :-) La configuración attr('value', ...)en jQuery <1.6 establece la propiedad, por lo que el valor actual cambia y el valor predeterminado no. En 1.6 establece el atributo, por lo que, en teoría, el valor predeterminado cambia y el valor actual no. Sin embargo, hay (más) inconsistencias en el navegador sobre qué hace exactamente la configuración del valueatributo. En IE también establece el valor actual; en algunos navegadores solo establece el valor actual si el valor actual no se ha establecido anteriormente. [llora]
bobince
1
Al igual que @Quentin dijo: "Los atributos están definidos por HTML. Las propiedades están definidas por DOM". La versión más simple que he leído.
Alan Dong
241

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 classatributo de una etiqueta cambiará la classNamepropiedad de esa etiqueta en el DOM. Si no tiene ningún atributo en una etiqueta, aún tiene la propiedad DOM correspondiente con un valor vacío o predeterminado.

Ejemplo: Si bien su etiqueta no tiene classatributo, la propiedad DOM classNameexiste 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.

Yunzen
fuente
Entonces, ¿esto significa que es mejor actualizar el atributo porque entonces se asegura de que el atributo y la propiedad se actualicen y estén alineados?
Lucas
1
@Luke the DOM es la representación técnica interna, el modelo. Los atributos HTML son una representación externa, una vista. Si cambia el uno, el otro será cambiado por un controlador, y viceversa.
Yunzen
@HerrSerker ¿Entonces ambos están sincronizados a través de un controlador? Supongo que esto solo está dentro de los métodos attr y prop de jQuery. Aquí hay una modificación de su violín donde exploro esto más, jsfiddle.net/v8wRy , y hasta ahora parecen ser equivalentes.
Lucas
3
"Si cambia uno, el otro será cambiado por un controlador, y viceversa. Este controlador no está en jQuery, sino en el código nativo de los navegadores". Esto no es cierto para la mayoría de los atributos / propiedades. Para la mayoría es solo una traducción unidireccional donde un atributo determina el valor inicial de la propiedad correspondiente. Las dos respuestas principales explican esto en detalle.
ᴠɪɴᴄᴇɴᴛ
@Vincent. No veo, donde las dos respuestas principales dicen algo contrario a mi respuesta. Por supuesto, la mayoría de los atributos son los valores iniciales de las propiedades DOM correspondientes. Pero son mutuamente dependientes. Pruebe algo como jQuery('p').prop('className', 'foo');en la consola de Chrome y verá cómo cada párrafo obtiene el classatributo thg de 'foo'. Por supuesto que no en el código fuente, que proviene del servidor. Eso es una constante.
Yunzen
140

Es solo la distinción entre los atributos HTML y los objetos DOM lo que causa confusión. Para aquellos que se sienten cómodos actuando sobre los elementos DOM, las propiedades nativas como this.src this.value this.checkedetc. .propes una 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 .attry .propes el siguiente ejemplo:

<input blah="hello">
  1. $('input').attr('blah'): vuelve 'hello'como se esperaba. No hay sorpresas aquí.
  2. $('input').prop('blah'): devuelve undefined, porque está intentando hacerlo [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'): vuelve 'apple'eh? ¿Por qué no "pera", ya que esto se estableció en último lugar en ese elemento. Debido a que la propiedad se modificó en el atributo de entrada, no en el elemento de entrada DOM en sí mismo, básicamente funcionan casi independientemente el uno del otro.
  2. $('input').prop('blah'): devoluciones 'pear'

Lo que realmente debe tener cuidado es simplemente no mezclar 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/


.attrvs .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')- devuelve 'hello'*
  • .prop('value') -- devoluciones 'i changed the value'

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

Gary Green
fuente
@Neal porque da referencia a la estructura de las funciones de jquery mejor. "$ ('input'). prop ('blah'): devuelve undefined, porque está tratando de hacer [HTMLInputElement] .blah, y no existe tal propiedad en ese objeto DOM. Solo existe en el ámbito como un atributo de ese elemento, es decir, [HTMLInputElement] .getAttribute ('blah') "
Uğur Gümüşhan
2
Parece diferente del documento, api.jquery.com/prop : "El método .prop () debe usarse para establecer deshabilitado y marcado en lugar del método .attr (). El método .val () debe usarse para obtener y fijando el valor."
cisne
53

TL; DR

Utilizar prop()más attr()en la mayoría de los casos.

Una 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

agjmills
fuente
1
si es posible, venga con algunas muestras fáciles de lo que dice y también muestre cuándo usar prop() and when to go for attr(). esperando respuesta :)
Mou
36

Control sucio

Este concepto proporciona 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 se marcaron.
  • desmarque ambas casillas de verificación.
  • haz clic en el botón nuevamente. Solo propse marcó la casilla de verificación. ¡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 disabledon 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"on input type="checkbox", las cosas se rompen, porque una vez que haces clic en él, se ensucia y luego agregar o quitar el checked="checked"atributo de contenido ya no alterna la verificación .

Esta es la razón por la que debe usar principalmente .prop, ya que afecta la propiedad efectiva directamente, en lugar de depender de los efectos secundarios complejos de modificar el HTML.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
fuente
Para completar también intente estas variaciones: 1) Antes de hacer clic en el botón, marque y luego desmarque la primera casilla de verificación 2) (Para esto, deberá cambiar el fragmento). Dé a la primera entrada un checkedatributo:checked="checked"
ᴠɪɴᴄᴇɴᴛ
33

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 propiedad al recuperar algunos atributos, lo que podría causar un comportamiento inconsistente. A partir de jQuery 1.6, el método .prop () proporciona una forma de recuperar explícitamente los valores de propiedad, mientras que .attr () recupera atributos.

¡Así que usa utilería!

Arnaud F.
fuente
2
Entonces, ¿eso significa que cuando cambie a 1.6, muchas cosas se romperán?
Naftali aka Neal
No, es solo un comportamiento inconsistente, si funciona antes, siempre funcionará con jQuery 1.6, es solo que el accesorio es más seguro;)
Arnaud F.
66
Me parece recordar. $.attr()recuperando propiedades la mayor parte del tiempo trabajé con él, no "a veces". La confusión causada por esto todavía resuena hoy. Lamentablemente, tengo muchos problemas para encontrar una lectura definitiva sobre los atributos HTML frente a las propiedades DOM, por lo que podría escribir una respuesta aquí en un momento.
3
@ Arnaud-f No es cierto. Todo el código anterior a 1.6 que usa attr ('marcado') para marcar casillas de verificación ahora estará roto.
CaptSaltyJack
3
@Matt McDonald: ¿Qué tipo de "... problemas para encontrar una lectura definitiva sobre los atributos HTML frente a las propiedades DOM ..." quieres decir? Las propiedades (reflejadas y de otro tipo) se describen en la especificación HTML DOM2 ; También es posible que deba consultar las especificaciones DOM2 y DOM3 .
TJ Crowder
28

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

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

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

La regla general es : el .prop()método debe usarse para atributos / propiedades booleanas y para propiedades que no existen en html (como window.location). Todos los demás atributos (los que puede ver en el html) pueden y deben seguir siendo manipulados 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()se prefiere (aunque .attr()todavía se puede usar).

mesa con uso preferido


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

  1. .prop()puede devolver cualquier tipo: cadena, entero, booleano; while .attr()siempre devuelve una cadena.
  2. .prop()se dice que es aproximadamente 2.5 veces más rápido que .attr().
Lakesare
fuente
algo ha cambiado, como estos: $('#myImageId').prop('src', 'http://example.com/img.png'), var class = $('.myDivClass').prop('class')o $('#myTextBox').prop('type', 'button'). Y así sucesivamente ...
@ Mr.Wolf, lo siento, todavía no entiendo lo que quieres decir. que ha cambiado'? La sintaxis siempre ha sido así.
Lakesare
Creo que la tabla en su respuesta es innecesaria. Porque .prop()funciona bien con todas las propiedades. No quieres marcar todas las propiedades en la .prop()columna, ¿verdad?
@ Mr.Wolf, creo que es necesario porque, como ya se dijo, "muestra dónde .prop()se prefiere (aunque .attr()todavía se puede usar)"
lakesare
Usualmente uso .attr()para definir un evento lo .prop()que no puede. De esta manera: $('.myDiv').attr('onclick', 'alert("Hello world!")'). Si cambias .attr()a .prop(), no funcionará. Totalmente, creo que no hay razón para usar .attr()para establecer u obtener valor id/class/href/checked/src...... Tenga en cuenta que no digo que esté equivocado.
20

.attr():

  • Obtenga el valor de un atributo para el primer elemento del conjunto de elementos coincidentes.
  • Le da el valor del elemento como se definió en el html en la carga de la página

.prop():

  • Obtenga el valor de una propiedad para el primer elemento del conjunto de elementos coincidentes.
  • Da los valores actualizados de los elementos que se modifican a través de javascript / jquery
Kgn-web
fuente
13

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. Obtener un atributo HTML que no se sincroniza con una propiedad DOM, por ejemplo, obtener el "valor original" de un atributo HTML estándar, como <input value="abc">.
naor
fuente
7

attributes -> HTML

properties -> DOM

NkS
fuente
8
Sé lo que quieres decir, pero HTML es un lenguaje de marcado, y el DOM una representación creada a partir del HTML. Un elemento DOME tiene atributos y propiedades .
t.niese
@ t.niese, attirbutestambién una de las propiedades deDOM
NkS
La respuesta corta es simple.
Nabi KAZ el
6

Antes de jQuery 1.6, el attr()método a veces tomaba en cuenta los valores de las propiedades al recuperar los atributos, lo que causaba un comportamiento bastante inconsistente.

La introducción del prop()método proporciona una forma de recuperar explícitamente los valores de propiedad, mientras .attr()recupera los atributos.

Los documentos:

jQuery.attr() Obtenga el valor de un atributo para el primer elemento del conjunto de elementos coincidentes.

jQuery.prop() Obtenga el valor de una propiedad para el primer elemento del conjunto de elementos coincidentes.

Gothburz
fuente
3

Recordatorio suave sobre el uso prop(), por ejemplo:

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

La función anterior se usa para verificar si checkbox1 está marcado o no, si está marcado: return 1; si no: devuelve 0. La función prop () se usa aquí como una función GET.

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

La función anterior se usa para configurar la casilla de verificación 1 para que se marque y SIEMPRE devuelva 1. Ahora la función prop () se usa como una función SET.

No te equivoques.

P / S: cuando reviso la propiedad Image src . Si el src está vacío, prop devuelve la URL actual de la página (incorrecto) y attr devuelve una cadena vacía (derecha).

usuario2657778
fuente
Estás equivocado en este ejemplo: <img src="smiley.gif" alt="Smiley face" width="42" height="42" onclick="alert($(this).prop('src'))">. Debería funcionar y devolver la ubicación de la imagen.
2

Una cosa .attr()puede hacer que .prop()no puede: afectar a los selectores CSS

Aquí hay un problema que no vi en las otras respuestas.

Selector de CSS [name=value]

  • responderá a .attr('name', 'value')
  • pero no siempre a .prop('name', 'value')

.prop() afecta solo unos pocos selectores de atributos

.attr() afecta a todos los selectores de atributos

Bob Stein
fuente
0

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

2) $ (elem) .attr ("marcado") (1.6.1+) "marcado" (Cadena) Cambiará con el estado de la casilla de verificación

3) $ (elem) .attr ("marcado") (anterior a 1.6) verdadero (booleano) Cambiado con el estado de la casilla de verificación

  • Principalmente queremos usar para objetos DOM en lugar de atributos personalizados como data-img, data-xyz.

  • También algunas de las diferencias al acceder al checkboxvalor y href con attr()y prop()como la cosa cambia con la salida DOM con prop()el enlace completo desde originy el Booleanvalor para la casilla de verificación (pre-1.6)

  • Solo podemos acceder a elementos DOM con propotros, entonces nos daundefined

Parth Trivedi
fuente
0

Hay algunas consideraciones más en prop () vs attr ():

  • selectedIndex, tagName, nodeName, nodeType, ownerDocument, defaultChecked y defaultSelected..etc deben recuperarse y establecerse con el método .prop (). Estos no tienen los atributos correspondientes y son solo propiedades.

  • Para el tipo de entrada casilla de verificación

       .attr('checked') //returns  checked
       .prop('checked') //returns  true
       .is(':checked') //returns true
  • El método prop devuelve un valor booleano para marcado, seleccionado, deshabilitado, readOnly..etc, mientras que attr devuelve una cadena definida. Por lo tanto, puede usar directamente .prop ('marcado') en condición if.

  • .attr () llama a .prop () internamente, por lo que el método .attr () será un poco más lento que acceder a ellos directamente a través de .prop ().

Rishu Ranjan
fuente
-2

La respuesta de Gary Hole es muy relevante para resolver el problema si el código está escrito de tal manera

obj.prop("style","border:1px red solid;")

Dado que la función prop devuelve el CSSStyleDeclarationobjeto, el código anterior no funcionará correctamente en algunos navegadores (probado IE8 with Chrome Frame Pluginen mi caso).

Cambiándolo así al siguiente código

obj.prop("style").cssText = "border:1px red solid;"

resuelve el problema.

zawhtut
fuente