getAttribute () versus propiedades del objeto Element?

92

Expresiones como Element.getAttribute("id")y Element.iddevuelven lo mismo.

¿Cuál debería usarse cuando necesitamos atributos de un objeto HTMLElement?

¿Hay algún problema entre navegadores con estos métodos como getAttribute()y setAttribute()?

¿O algún impacto en el rendimiento entre el acceso directo a las propiedades del objeto y el uso de estos métodos de atributos?

PK
fuente
1
Pregunta similar: Propiedades y atributos en HTML
sleske

Respuestas:

126

getAttributerecupera el atributo de un elemento DOM, mientras el.idrecupera la propiedad de este elemento DOM. Ellos no son los mismos.

La mayoría de las veces, las propiedades DOM se sincronizan con atributos.

Sin embargo, la sincronización no garantiza el mismo valor . Un ejemplo clásico es entre el.hrefy el.getAttribute('href')para un elemento de anclaje.

Por ejemplo:

<a href="/" id="hey"></a>
<script>
var a = document.getElementById('hey')
a.getAttribute('href') // "/"
a.href // Full URL except for IE that keeps '/'
</script>

Este comportamiento ocurre porque de acuerdo con el W3C , la propiedad href debe ser un enlace bien formado. La mayoría de los navegadores respetan este estándar (¿adivinen quién no?).

Hay otro caso para la input's checkedpropiedad. La propiedad DOM devuelve trueo falsemientras el atributo devuelve la cadena "checked"o una cadena vacía.

Y luego, hay algunas propiedades que se sincronizan en un solo sentido . El mejor ejemplo es la valuepropiedad de un inputelemento. Cambiar su valor a través de la propiedad DOM no cambiará el atributo (editar: verifique el primer comentario para mayor precisión).

Por estas razones, le sugiero que siga usando las propiedades DOM , y no los atributos, ya que su comportamiento difiere entre los navegadores.

En realidad, solo hay dos casos en los que necesita usar los atributos:

  1. Un atributo HTML personalizado, porque no está sincronizado con una propiedad DOM.
  2. Para acceder a un atributo HTML incorporado, que no está sincronizado desde la propiedad, y está seguro de que necesita el atributo (por ejemplo, el original valuede un inputelemento).

Si desea una explicación más detallada, le sugiero que lea esta página . Le llevará solo unos minutos, pero estará encantado con la información (que resumí aquí).

Florian Margaine
fuente
9
+1 por un buen consejo en general. Sin embargo, el tema valuede la sincronización está un poco apagado: la propiedad de una entrada obtiene su valor inicial del atributo, pero por lo demás no está vinculada a él en absoluto. En cambio, el valueatributo está completamente sincronizado con la defaultValuepropiedad. Asimismo checkedy defaultChecked. Excepto en IE antiguo (<= 7 y modos de compatibilidad posteriores), que se ha roto getAttribute()y setAttribute().
Tim Down
Agregó su comentario como "explicación adicional" :-)
Florian Margaine
2
Creo que se equivocó en el primer ejemplo. a.hrefdevuelve la URL completa, a.getAttribute("href")devuelve el atributo exactamente como defiend en la fuente HTML.
Salman A
Si está tratando de averiguar si un valor no es el predeterminado, es mejor que use atributos. Muchos navegadores modernos devolverán un valor predeterminado (p input.formAction. Ej. ) O una cadena vacía (p a.download. Ej. ), Lo que hace que las cosas sean ambiguas. La única excepción son los valores que no están sincronizados en dos direcciones, como value.
Kevin Li
Si id no se establece en absoluto en el dom, getAttribute devolverá nulo y element.id devolverá una cadena vacía. ¿Es esto un estándar?
Maciej Krawczyk
11

getAttribute('attribute') normalmente devuelve el valor del atributo como una cadena, exactamente como se define en el código fuente HTML de la página.

Sin embargo, element.attributepodría devolver un valor normalizado o calculado del atributo. Ejemplos:

  • <a href="https://stackoverflow.com/foo"></a>
    • a.href contendrá la URL completa
  • <input type="checkbox" checked>
    • input.checked será verdadero (booleano)
  • <input type="checkbox" checked="bleh">
    • input.checked será verdadero (booleano)
  • <img src='http://dummyimage.com/64x64/000/fff'>
    • img.width será 0 (número) antes de que se cargue la imagen
    • img.width será 64 (número) cuando se cargue la imagen (o los primeros bytes)
  • <img src='http://dummyimage.com/64x64/000/fff' width="50%">
    • img.width será el 50% calculado
  • <img src='http://dummyimage.com/32x32/000/fff' style='width: 50px'>
    • img.width será 50 (número)
  • <div style='background: lime;'></div>
    • div.style será un objeto
Salman A
fuente
3

De acuerdo con esta prueba jsPerf getAttribute es más lenta que la idpropiedad.

PD

Curiosamente, ambas declaraciones funcionan muy mal en IE8 (en comparación con otros navegadores).

mamoo
fuente
3

Utilice siempre las propiedades a menos que tenga una razón específica para no hacerlo.

  • getAttribute()y setAttribute()están rotos en IE más antiguos (y en modo de compatibilidad en versiones posteriores)
  • las propiedades son más convenientes (en particular, las correspondientes a atributos booleanos)

Hay algunas excepciones :

  • acceder a los atributos de los <form>elementos
  • acceder a atributos personalizados (aunque desaconsejaría el uso de atributos personalizados)

He escrito sobre este tema varias veces en SO:

Tim Down
fuente
Antes de IE 8, las propiedades y los atributos se trataban de forma idéntica . Como mencionó anteriormente, las propiedades son el camino a seguir.
@MattMcDonald: Sí, ese es el quebrantamiento al que aludía. No lo amplié en esta respuesta porque sentí que lo había hecho lo suficiente en otras respuestas a las que me vinculé :)
Tim Down
3

.idguarda la sobrecarga de la llamada a la función. (que es muy pequeño, pero preguntaste).

gdoron está apoyando a Monica
fuente
Hola gdoron, solo por curiosidad: traté de encontrar una explicación 'oficial' de esto (más allá de la prueba empírica, que es bastante clara;)) pero sin éxito. ¿Tiene algún enlace al respecto?
mamoo
0

Pruebe el siguiente ejemplo para comprender esto completamente. Para el DIV a continuación

<div class="myclass"></div>

El Element.getAttribute('class')volverá, myclasspero debe usar el Element.classNameque lo recupera de la propiedad DOM.

Hrushikesh
fuente
0

Un área donde esto marca una gran diferencia es con el estilo CSS basado en atributos.

Considera lo siguiente:

const divs = document.querySelectorAll('div');

divs[1].custom = true;
divs[2].setAttribute('custom', true);
div {
  border: 1px solid;
  margin-bottom: 8px;
}

div[custom] {
  background: #36a;
  color: #fff;
}
<div>A normal div</div>
<div>A div with a custom property set directly.</div>
<div>A div with a custom attribute set with `setAttribute`</div>

El div con la propiedad personalizada establecida directamente no refleja el valor del atributo y no es seleccionado por nuestro selector de atributos ( div[custom]) en el CSS.

setAttributeSin embargo, el div con el atributo personalizado establecido usando se puede seleccionar usando un selector de atributo css y diseñarlo en consecuencia.

Jsilvermist
fuente