¿Cuál es la diferencia entre propiedades y atributos en HTML?

408

Después de los cambios realizados en jQuery 1.6.1, he estado tratando de definir la diferencia entre propiedades y atributos en HTML.

Mirando la lista en las notas de la versión jQuery 1.6.1 (cerca de la parte inferior), parece que uno puede clasificar las propiedades y atributos HTML de la siguiente manera:

  • Propiedades: todo lo que tiene un valor booleano o que es UA calculado, como selectedIndex.

  • Atributos: 'Atributos' que se pueden agregar a un elemento HTML que no es booleano ni contiene un valor generado por UA.

Pensamientos?

schalkneethling
fuente
66
Posible duplicado de .prop () vs .attr ()
Naftali aka Neal

Respuestas:

826

Al escribir código fuente HTML, puede definir atributos en sus elementos HTML. Luego, una vez que el navegador analiza su código, se creará un nodo DOM correspondiente. Este nodo es un objeto y, por lo tanto, tiene propiedades .

Por ejemplo, este elemento HTML:

<input type="text" value="Name:">

tiene 2 atributos ( typey value).

Una vez que el navegador analiza este código, se creará un objeto HTMLInputElement , y este objeto contendrá docenas de propiedades como: aceptar, accessKey, alinear, alt, atributos, enfoque automático, baseURI, marcado, childElementCount, childNodes, children, classList, className, altura del cliente, etc.

Para un objeto de nodo DOM dado, las propiedades son las propiedades de ese objeto y los atributos son los elementos de la attributespropiedad de ese objeto.

Cuando se crea un nodo DOM para un elemento HTML dado, muchas de sus propiedades se relacionan con atributos con el mismo nombre o nombres similares, pero no es una relación uno a uno. Por ejemplo, para este elemento HTML:

<input id="the-input" type="text" value="Name:">

el nodo DOM correspondiente tendrá id, typey valuepropiedades (entre otros):

  • La idpropiedad es una propiedad reflejada para el idatributo: obtener la propiedad lee el valor del atributo y establecer la propiedad escribe el valor del atributo. ides una propiedad puramente reflejada, no modifica ni limita el valor.

  • La typepropiedad es una propiedad reflejada para el typeatributo: obtener la propiedad lee el valor del atributo y establecer la propiedad escribe el valor del atributo. typeno es una propiedad reflejada pura porque está limitada a valores conocidos (por ejemplo, los tipos válidos de una entrada). Si lo tuvieras <input type="foo">, entonces theInput.getAttribute("type")te da "foo"pero theInput.typete da "text".

  • Por el contrario, la valuepropiedad no refleja el valueatributo. En cambio, es el valor actual de la entrada. Cuando el usuario cambia manualmente el valor del cuadro de entrada, la valuepropiedad reflejará este cambio. Entonces, si el usuario ingresa "John"en el cuadro de entrada, entonces:

    theInput.value // returns "John"

    mientras:

    theInput.getAttribute('value') // returns "Name:"

    La valuepropiedad refleja el contenido de texto actual dentro del cuadro de entrada, mientras que el valueatributo contiene el contenido de texto inicial del valueatributo del código fuente HTML.

    Entonces, si desea saber qué hay actualmente dentro del cuadro de texto, lea la propiedad. Sin embargo, si desea saber cuál era el valor inicial del cuadro de texto, lea el atributo. O puede usar la defaultValuepropiedad, que es un puro reflejo del valueatributo:

    theInput.value                 // returns "John"
    theInput.getAttribute('value') // returns "Name:"
    theInput.defaultValue          // returns "Name:"

Hay varias propiedades que reflejan directamente su atributo ( rel, id), algunos son reflejos directos con ligeramente diferentes nombres ( htmlForrefleja el foratributo, classNamerefleja el classatributo), muchos que reflejan su atributo pero con restricciones / modificaciones ( src, href, disabled, multiple), etc. en. La especificación cubre los diversos tipos de reflexión.

Šime Vidas
fuente
1
Hola Sime, supongo que esto es bastante ambiguo, especialmente si echas un vistazo aquí: w3.org/TR/html4/index/attributes.html , y no hay una respuesta clara. Básicamente, uno debe seguir lo que se indica en el resumen en el blog jQuery e incluso entonces, uno se asignará al otro y funcionará en ambos casos con un ligero impacto en el rendimiento si usa incorrectamente el accesorio cuando necesita usar attr
schalkneethling
44
@oss Su enlace hace referencia a una lista de atributos HTML. Esa lista no es ambigua, esos son atributos.
Šime Vidas
¿Hay algunos documentos sobre la relación? @ ŠimeVidas
SKing7
3
¿Dónde podría encontrar una lista completa de atributos para las propiedades (como for-> htmlFor) y, de manera similar, una lista de propiedades que toman su valor inicial de un atributo, pero no lo reflejan ( input.value). Espero que esto esté en algún lugar de la fuente de una biblioteca como github.com/Matt-Esch/virtual-dom pero no está realmente documentado.
sstur
1
@Pim No lo he leído yo mismo, pero esta serie de artículos de 4 partes parece un gran recurso: twitter.com/addyosmani/status/1082177515618295808
Šime Vidas el
53

Después de leer la respuesta de Sime Vidas , busqué más y encontré una explicación muy directa y fácil de entender en los documentos angulares .

Atributo HTML versus propiedad DOM


Los atributos están definidos por HTML. Las propiedades están definidas por el DOM (Modelo de objeto de documento).

  • Algunos atributos HTML tienen una asignación 1: 1 a las propiedades. idEs un ejemplo.

  • Algunos atributos HTML no tienen propiedades correspondientes. colspanEs un ejemplo.

  • Algunas propiedades DOM no tienen los atributos correspondientes. textContent Es un ejemplo.

  • Parece que muchos atributos HTML se correlacionan con propiedades ... ¡pero no de la manera que piensas!

Esa última categoría es confusa hasta que comprenda esta regla general:

Los atributos inicializan las propiedades DOM y luego se hacen. Los valores de las propiedades pueden cambiar; los valores de los atributos no pueden.

Por ejemplo, cuando se visualiza el navegador <input type="text" value="Bob">, crea un nodo DOM correspondiente con una valuepropiedad inicializada en "Bob".

Cuando el usuario ingresa "Sally" en el cuadro de entrada, la value propiedad del elemento DOM se convierte en "Sally". Pero el value atributo HTML permanece sin cambios a medida que descubre si le pregunta al elemento de entrada acerca de ese atributo: input.getAttribute('value')devuelve "Bob".

El atributo HTML valueespecifica el valor inicial ; La value propiedad DOM es el valor actual .


El disabledatributo es otro ejemplo peculiar. La disabledpropiedad de un botón es falsepor defecto, por lo que el botón está habilitado. Cuando agrega el disabledatributo, solo su presencia inicializa la disabledpropiedad del botón para trueque el botón esté deshabilitado.

Agregar y eliminar el disabledatributo deshabilita y habilita el botón. El valor del atributo es irrelevante, por lo que no puede habilitar un botón escribiendo<button disabled="false">Still Disabled</button>.

Establecer la disabled propiedad del botón deshabilita o habilita el botón. El valor de la propiedad importa.

El atributo HTML y la propiedad DOM no son lo mismo, incluso cuando tienen el mismo nombre.

subtleseeker
fuente
Este ejemplo no es correcto: el colspanatributo tiene la colSpanpropiedad ... Entonces, ¿qué atributo no tiene una propiedad relacionada ahora?
Robert Siemer
46

Las respuestas ya explican cómo los atributos y las propiedades se manejan de manera diferente, pero realmente me gustaría señalar lo totalmente loco que es esto. Incluso si es hasta cierto punto la especificación.

Es una locura tener algunos de los atributos (por ejemplo , id, class, foo, bar ) para retener solo un tipo de valor en el DOM, mientras que algunos atributos (por ejemplo , marcado, seleccionado ) para retener dos valores; es decir, el valor "cuando se cargó" y el valor del "estado dinámico". (¿No se supone que el DOM debe representar el estado del documento en toda su extensión?)

Es absolutamente esencial que dos campos de entrada , por ejemplo, un texto y una casilla de verificación se comporten de la misma manera . Si el campo de entrada de texto no retiene un valor separado "cuando se cargó" y el valor "actual, dinámico", ¿por qué la casilla de verificación? Si la casilla de verificación tiene dos valores para el atributo marcado , ¿por qué no tiene dos para sus atributos de clase e id ? Si espera cambiar el valor de un campo de entrada de texto * y espera que el DOM (es decir, la "representación serializada") cambie y refleje este cambio, ¿por qué no esperaría lo mismo de un campo de entrada de tipo casilla de verificación en el atributo marcado?

La diferenciación de "es un atributo booleano" simplemente no tiene ningún sentido para mí, o al menos no es una razón suficiente para esto.

sibidiba
fuente
21
Esta no es una respuesta, pero estoy de acuerdo contigo; Es totalmente una locura.
Samuel
Sí, este concepto apesta y no debería ser tan estandarizado. Este fue uno de los casos (como innerHTML, por ejemplo) que era bueno en el antiguo IE y debería haber sido adoptado por los estándares. Las propiedades y los atributos se sincronizaron siempre que fue posible, incluso los atributos personalizados, lo que hizo una muy buena sintaxis de js dot legible. HTML5 hace que las etiquetas HTML personalizadas sean ciudadanos de primera clase, los atributos personalizados también deberían serlo. Esta característica se eliminó ya que el antiguo IE sigue siendo un problema real: solo ahora estamos viendo muchas empresas tradicionalmente atrapadas con IE para sistemas antiguos que ahora las encuentran rotas en IE10.
Mike Nelson
48
No es una locura. Has entendido mal. El checkedatributo está representado por la defaultCheckedpropiedad (del mismo modo para una entrada de texto, el valueatributo está representado por la defaultValuepropiedad). Se checkedrequiere una segunda propiedad, para representar si la casilla de verificación está marcada porque esta es una parte intrínseca de la funcionalidad de una casilla de verificación: es interactiva y el usuario puede cambiarla (y restablecerla al valor predeterminado, si está presente un botón de restablecimiento de formulario) , de una manera que otro atributo como idno es. No tiene nada que ver con el hecho de que es un atributo booleano.
Tim Down
3
@TimDown - Gracias. ¿Eso realmente me superó el WTF? joroba.
pedz
12
@TimDown Sigo sintiendo que es "una locura" porque cualquier enfoque lógico haría que el nombre de la propiedad y el nombre del atributo coincidan, o al menos no tengan un nombre de atributo y un nombre de propiedad que no estén relacionados (es decir, el atributo marcado se refiere a defaultChecked propiedad mientras la propiedad marcada no está relacionada). De hecho, el enfoque lógico que todos asumen es que el caso al principio sería no separar los atributos y propiedades en absoluto. Los atributos no deben ser inmutables, sino que siempre deben reflejar los valores de las propiedades. No debería haber una distinción entre los dos.
dallin
10

bueno, estos son especificados por el w3c qué es un atributo y qué es una propiedad http://www.w3.org/TR/SVGTiny12/attributeTable.html

pero actualmente attr y prop no son tan diferentes y hay casi lo mismo

pero prefieren accesorios para algunas cosas

Resumen de uso preferido

El método .prop () 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 método .attr ().

bueno, en realidad no tienes que cambiar algo si usas attr o prop o ambos, ambos funcionan, pero vi en mi propia aplicación que el accesorio funcionaba donde atrr no funcionaba, así que tomé mi aplicación 1.6 prop =)

Daniel Ruf
fuente
Hola Daniel, leí eso. Parece que hay una definición clara para separar los dos, ya que parte de lo que Sime menciona a continuación también se puede agregar al elemento HTML, por ejemplo, alt. Seguiremos leyendo algunas de las especificaciones HTML y veremos si de hecho hay una manera de distinguirlas claramente en la práctica.
schalkneethling
3
Ese documento se relaciona con SVG, no con HTML.
Luzado
5

Diferencia de propiedades y atributos HTML:

Primero veamos las definiciones de estas palabras antes de evaluar cuál es la diferencia en HTML:

Definición en inglés:

  • Los atributos se refieren a información adicional de un objeto.
  • Las propiedades describen las características de un objeto.

En contexto HTML:

Cuando el navegador analiza el HTML, crea una estructura de datos de árbol que básicamente es una representación en memoria del HTML. La estructura de datos del árbol contiene nodos que son elementos HTML y texto. Los atributos y las propiedades se relacionan con esto de la siguiente manera:

  • Los atributos son información adicional que podemos poner en el HTML para inicializar ciertas propiedades DOM.
  • Las propiedades se forman cuando el navegador analiza el HTML y genera el DOM. Cada uno de los elementos en el DOM tiene su propio conjunto de propiedades que el navegador establece. Algunas de estas propiedades pueden tener su valor inicial establecido por atributos HTML. Cada vez que cambie una propiedad DOM que tenga influencia en la página renderizada, la página será renderizada inmediatamente

También es importante darse cuenta de que la asignación de estas propiedades no es de 1 a 1. En otras palabras, no todos los atributos que le damos a un elemento HTML tendrán una propiedad DOM similar.

Además tienen diferentes elementos DOM diferentes propiedades. Por ejemplo, un <input>elemento tiene una propiedad de valor que no está presente en una <div>propiedad.

Ejemplo:

Tomemos el siguiente documento HTML:

 <!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">  <!-- charset is a attribute -->
  <meta name="viewport" content="width=device-width"> <!-- name and content are attributes -->
  <title>JS Bin</title>
</head>
<body>
<div id="foo" class="bar foobar">hi</div> <!-- id and class are attributes -->
</body>
</html>

Luego inspeccionamos <div>, en la consola JS:

 console.dir(document.getElementById('foo'));

Vemos las siguientes propiedades DOM (devtools de Chrome, no se muestran todas las propiedades):

propiedades y atributos html

  • Podemos ver que la identificación del atributo en el HTML ahora también es una propiedad de identificación en el DOM. El id ha sido inicializado por el HTML (aunque podríamos cambiarlo con javascript).
  • Podemos ver que el atributo de clase en el HTML no tiene propiedad de clase correspondiente ( classes una palabra clave reservada en JS). Pero en realidad 2 propiedades, classListy className.
Willem van der Veen
fuente