javascript - elementos - Razón de diseño detrás de la relación entre la propiedad del elemento y su atributo correspondiente
dom javascript pdf (2)
Estoy desconcertado por la razón detrás de cómo funciona la relación entre la property
algún elemento DOM y sus attributes
correspondientes.
A continuación se muestra un gráfico del libro jquery in action 2015 Bear Bibeault
, que muestra la relación entre la property
y el attribute
del elemento DOM.
Para explicar con más detalle el concepto, el autor tuvo el siguiente código y explicación para el código.
Mi pregunta es, ¿por qué algunas property
y attribute
están sincronizados, por qué algunas no están sincronizadas y por qué algunos attributes
no tienen la property
correspondiente?
He encontrado una excelente publicación que explica la relación entre property
y attribute
, pero no mencionó por qué se diseñó de esta manera. Espero entender las razones detrás del diseño.
Una pregunta relacionada, si quiero obtener o establecer un valor en un elemento DOM, ¿debo obtener / establecer la property
o el attribute
?
¿Y cómo encontramos la relación entre una property
particular y su attribute
correspondiente cuando lo necesitamos? ¿Hay alguna documentación que detalla específicamente la relación?
DOM es algo que ha crecido "naturalmente" en gran medida. Hay que tener en cuenta que el HTML (que significa: atributos) fue lo primero y originalmente no había scripts en absoluto. Finalmente, Netscape introdujo JavaScript con lo que consideraría una API extremadamente limitada hoy. Esta API estaba orientada a la manipulación de formularios, no a elementos HTML realmente arbitrarios. Y luego Netscape e Internet Explorer presentaron diferentes variantes de lo que llamaron DHTML en ese entonces (HTML dinámico). La variante de Netscape se basó en una etiqueta especial <layer>
y nadie la recuerda hoy. La variante de Internet Explorer permitió un acceso más genérico a los elementos HTML y, en particular, tenía una asignación 1: 1 de atributos a propiedades.
Mientras que Internet Explorer ganó esta guerra, su variante DHTML se diseñó cuando la gente pensaba en los nombres de atributos HTML como una colección fija. Con atributos arbitrarios, tenía demasiados problemas. Por ejemplo:
- El atributo de
class
no pudo asignarse a JavaScript originalmente porque laclass
es una palabra clave reservada. Si bien los cambios posteriores al estándar de JavaScript permitieron usar palabras clave reservadas como nombres de propiedades, Internet Explorer tiene que asignar el atributo declass
a la propiedadclassName
. Establecer el atributoclassName
en un elemento o la propiedadel["class"]
en un objeto de JavaScript resultó en inconsistencias hilarantes. - Los atributos de HTML distinguen entre mayúsculas y minúsculas, mientras que las propiedades de JavaScript distinguen entre mayúsculas y minúsculas. Así que Internet Explorer tenía todo tipo de hacks para reconocer la intención. ¿Qué sucedió cuando el elemento era
<FOO SOMEATTIRIBUTE>
e intentaste acceder ael.someAttribute
oel.SOMEATTRIBUTE
desde JavaScript? Ya no lo recuerdo, pero no era bonito. - Los objetos de JavaScript siempre tienen métodos también. Un atributo
toString
por ejemplo, no se puede asignar a una propiedad porque enmascararía el métodotoString()
.
Ningún otro navegador aparte de Internet Explorer implementó este mapeo 1: 1 de atributos a propiedades, e incluso Internet Explorer se rindió tan pronto como fue posible en términos de compatibilidad con versiones anteriores (esto llevó mucho tiempo). En su lugar, los atributos y las propiedades se tratan como espacios de nombres separados ahora. Los navegadores le proporcionarán algunas propiedades como accesos directos para el acceso y la manipulación de atributos, pero en realidad solo están ahí para su conveniencia. Y hay algunos casos de compatibilidad con versiones anteriores que enturbian las aguas: la propiedad de value
y el atributo de value
no se asignan entre sí, el primero refleja el estado actual del elemento mientras que el último refleja su estado inicial.
Edición : Solo para referencia, usted está citando la siguiente declaración:
Si el atributo existe como una propiedad incorporada pero es un valor booleano, el valor no está sincronizado.
Esto es incorrecto, el comportamiento no tiene nada que ver con booleanos contra cadenas. Como se mencionó anteriormente, a la propiedad de value
le falta sincronización de manera similar a la propiedad checked
. Por otro lado, la propiedad hidden
booleana se sincronizará correctamente con el atributo correspondiente. Por lo que puedo decir, encontrará la sincronización faltante entre la propiedad y el atributo en torno a las API de manipulación de formularios originales que ha introducido Netscape; esto es simplemente compatibilidad con versiones anteriores.
Así que tal vez no deberías confiar en las personas que escriben libros sobre jQuery con preguntas de DOM. Después de todo, estos decidieron explícitamente dejar de tocar el DOM directamente y optaron por una representación completamente diferente con su propio conjunto de peculiaridades.
Encontrarás las respuestas enterradas dentro de las especificaciones HTML. Primero quiero que vea los atributos y las propiedades del elemento de input
(encabezado "Atributos de contenido" y "Interfaz DOM") y la sección sobre reflexión de atributos (primer párrafo).
Notará que todos los atributos tienen propiedades correspondientes y la manipulación de una propiedad cambiará el atributo que refleja. Cabe resaltar que:
(1) Un atributo podría ser reflejado por una propiedad con un nombre ligeramente diferente. El ejemplo clásico es el atributo de class
que se refleja en la propiedad className
y for
atributo que se refleja en la propiedad htmlFor
.
(2) Del mismo modo, el atributo checked
se refleja en la propiedad defaultChecked
mientras que la propiedad checked
representa el estado interno de la casilla de verificación independientemente del atributo checked
. Esto siempre ha causado confusión entre los programadores (y autores de libros). La diferencia se explica al final de esta respuesta.
(3) Los atributos inventados (como el atributo "libro" en su ejemplo) no generarán la propiedad correspondiente y viceversa. Para este propósito, las especificaciones HTML describen un mecanismo llamado atributos de datos y propiedad de dataset
.
Una pregunta relacionada, si quiero obtener o establecer un valor en un elemento DOM, ¿debo obtener / establecer la
property
o elattribute
?
Depende. Por ejemplo, ambos de los siguientes producen resultados idénticos y HTML:
document.getElementById("div-1").title = "Hello";
document.getElementById("div-1").setAttribute("title") = "Hello";
Sin embargo, para los elementos de formulario, debe manipular el estado en lugar del atributo. Supongamos que tiene este formato HTML:
<input type="checkbox" id="checkbox-1">
Y usted ejecuta cualquiera de los siguientes:
document.getElementById("checkbox-1").defaultChecked = true;
document.getElementById("checkbox-1").setAttribute("checked", "checked");
Y aqui esta el resultado:
<input type="checkbox" id="checkbox-1" checked="checked">
Pero si la casilla de verificación realmente se comprueba depende de la suciedad del control (es decir, si se cambió su estado en algún momento). Para los elementos del formulario, normalmente manipularía las propiedades que corresponden al estado interno:
document.getElementById("checkbox-1").checked = true;