javascript - insertar - ¿Qué es mejor, agregar nuevos elementos a través de funciones DOM o agregar cadenas con etiquetas HTML?
llamar archivo javascript desde html (5)
He visto algunos métodos diferentes para agregar elementos al DOM. Los más prevenientes parecen ser, por ejemplo,
document.getElementById(''foo'').innerHTML =''<p>Here is a brand new paragraph!</p>'';
o
newElement = document.createElement(''p'');
elementText = document.createTextNode(''Here is a brand new parahraph!'');
newElement.appendChild(elementText);
document.getElementById(''foo'').appendChild(newElement);
pero no estoy seguro de las ventajas de hacer cualquiera de los dos. ¿Existe una regla general sobre cuándo se debe hacer uno sobre el otro, o uno de ellos está completamente equivocado?
Algunas notas:
Usar
innerHTML
es más rápido en IE, pero más lento en chrome + firefox. Aquí hay un punto de referencia que muestra esto con un conjunto constantemente variable de<div>
s +<p>
s; jsperf.com/dom-table-generation muestra esto para una<table>
constante y simple.Por otro lado, los métodos DOM son el estándar tradicional -
innerHTML
está estandarizado en HTML5 - y le permiten retener referencias a los elementos recién creados, para que pueda modificarlos más tarde.Debido a que innerHTML es rápido (suficiente), conciso y fácil de usar, es tentador apoyarse en él para cada situación. Pero tenga en cuenta que el uso de
innerHTML
separa todos los nodos DOM existentes del documento. Aquí hay un ejemplo que puedes probar en esta página.Primero, creemos una función que nos permita comprobar si un nodo está en la página:
function contains(parent, descendant) { return Boolean(parent.compareDocumentPosition(descendant) & 16); }
Esto devolverá
true
siparent
contienedescendant
. Pruébalo así:var p = document.getElementById("portalLink") console.log(contains(document, p)); // true document.body.innerHTML += "<p>It''s clobberin'' time!</p>"; console.log(contains(document, p)); // false p = document.getElementById("portalLink") console.log(contains(document, p)); // true
Esto se imprimirá:
true false true
Puede que no parezca que nuestro uso de
innerHTML
debería haber afectado nuestra referencia al elementoportalLink
, pero lo hace. Necesita ser recuperado nuevamente para un uso apropiado.
El primero es sencillo, más fácil de leer, menos código y puede ser más rápido.
El segundo le da mucho más control sobre el elemento que crea, es decir, hace que sea mucho más fácil modificar el nuevo Elemento usando JS (como adjuntar eventos, o simplemente usarlo en su código).
La segunda forma es para "puristas" a quienes les gusta el código "limpio" (no rápido y sucio).
Yo digo, use ambos, vea qué le queda mejor y vaya con eso.
Hay una serie de diferencias:
-
innerHTML
solo ha sido estandarizado por el W3C para HTML 5; a pesar de que ha sido un estándar de facto desde hace un tiempo en todos los navegadores populares, técnicamente en HTML 4 es una extensión de proveedor que los desarrolladores que cumplen con los estándares nunca serían atrapados usando. Por otro lado, es mucho más conveniente y prácticamente es compatible con todos los navegadores. -
innerHTML
reemplaza el contenido actual del elemento (no le permite modificarlo ). Pero nuevamente, ganas en conveniencia si no te importa esta limitación. -
innerHTML
se ha medido para que sea mucho más rápido (es cierto, esa prueba implica navegadores de versiones anteriores que no se usan ampliamente en la actualidad). -
innerHTML
puede representar un riesgo de seguridad (XSS) si se establece en un valor proporcionado por el usuario que no se ha codificado correctamente (por ejemplo,el.innerHTML = ''<script>...''
).
En base a lo anterior, parece que una conclusión práctica podría ser:
- Si no le molesta el hecho de que
innerHTML
es un poco limitante (solo reemplazo total del subárbol DOM enraizado en el elemento objetivo) y no arriesga una vulnerabilidad al inyectar contenido proporcionado por el usuario, úselo. De lo contrario, ve con DOM.
Según estos datos de referencia , recibirá innerHTML
resultados mucho más rápidos que la creación de elementos DOM. Está especialmente claro cuando se usan versiones anteriores de IE.
Siempre prefiero la legibilidad a menos que la diferencia de rendimiento sea extrema. En un caso aislado de esto, probablemente será una diferencia marginal.
En un caso innerHTML
como este, establecer la propiedad innerHTML
será más fácil de leer.
Pero si está haciendo mucha generación de contenido programático en JavaScript, es más limpio y fácil de leer y comprender la opción DOM.
Ejemplo:
Compare este código innerHTML
:
// Takes input of a value between 1 and 26, inclusive,
// and converts it to the appropriate character
function alphaToChar(alpha)
{
return String.fromCharCode(''a''.charCodeAt() + alpha - 1);
}
var content = "<ul>";
for(i = 0; i < 10; ++i)
{
content += "<li>";
for(j = 1; j <= 26; ++j)
{
content += "<a href=/"" + alphaToChar(j) + ".html/">"
+ alphaToChar(j)
+ "</a>";
}
content += "</li>";
}
document.getElementById("foo").innerHTML = content;
Para este código DOM:
// Takes input of a value between 1 and 26, inclusive,
// and converts it to the appropriate character
function alphaToChar(alpha)
{
return String.fromCharCode(''a''.charCodeAt() + alpha - 1);
}
var list = document.createElement("ul");
for(i = 0; i < 10; ++i)
{
var item = document.createElement("li");
for(j = 1; j <= 26; ++j)
{
var link = document.createElement("a");
link.setAttribute("href", alphaToChar(j) + ".html");
link.innerText = alphaToChar(j);
item.appendChild(link);
}
list.appendChild(item);
}
document.getElementById("foo").appendChild(list);
En este nivel comienzan a ser bastante similares en longitud.
Pero el código DOM será más fácil de mantener y es menos probable que cometas un error tipográfico o un error que sea difícil de diagnosticar, como omitir una etiqueta de cierre. O bien sus elementos estarán en su documento, o no lo harán.
- Con escenarios más complicados (como la construcción de menús treed), probablemente salga adelante con el código DOM.
- Con los escenarios en los que tiene que agregar varios tipos de contenido para construir un documento con contenido más heterogéneo, se convierte en un éxito. No es necesario que se asegure de llamar al código de anexión de su hijo antes de llamar al código de anexión principal.
- Con escenarios donde se agrega, elimina o modifica el contenido estático existente, DOM generalmente ganará.
Si comienzas a hacer modificaciones DOM complicadas (una de las últimas cosas que mencioné), definitivamente querrás consultar una biblioteca basada en modificaciones DOM, como jQuery .