Contenido

DOM como alternativa a innerHTML

18 dic

+ 27

Hasta hace unos meses, bastantes ya, creía que innerHTML era lo mejor que existía, pero debido a varios problemas con los que el uso hace que encuentres me di cuenta que no podía estar más equivocado. Este artículo que me he encontrado en mi del.icio.us relata las alternativas a este método.

¿Que problemas tenemos con innerHTML?

  • Para empezar innerHTML no es estandard, osea es propiedad de M$, y por ello ya no puede tener nada bueno.
  • Las aplicaciones futuras basadas en el MIME Type application/xhtml+xm se supone que no soportará esta propiedad en un futuro.
  • La propiedad funciona como un String, dejando fuera cualquier interacción con el DOM que intentamos introducir/sacar.
  • Al tratarse de una cadena de texto, obtenemos problemas en algunos casos con comillas, aperturas de tags y demás, ejemplos los comentarios de esta página.

Crear multiples elementos

A partir de un Array, decidimos crear una lista de elementos mediante innerHTML y despues usando DOM.

innerHTML:
data = new Array("one","two","three");
mHTML = "<ul>";
for(i=0;i<data.length;i++) {
	mHTML+="<li>" + data[i] + "</li>";
}
mHTML+="</ul>";
document.getElementById("mContainer").innerHTML = mHTML;

De esta forma definimos todo el HTML necesario con el que construiremos nuestra lista, usando propiedades DOM la cosa sería asi.

data = new Array("one","two","three");
 // create the UL element that our LI elements will descend from
eUL = document.createElement("ul");
// loop over the length of the "data" array
for(i=0;i<data.length;i++) {
	// create an LI
	eLI = document.createElement("li");
	// append the value of data[i] to the LI as a text node
	eLI.appendChild(document.createTextNode(data[i]));
	// append the LI to the UL
	eUL.appendChild(eLI);
}
// append the UL to the "mContainer" element.
document.getElementById("mContainer").appendChild(eUL);

Conclusion

Pese a ser más engorroso el código, esto nos permite posteriormente recorrer este código y modificarlo como si se tratase de contenido cargado con la página inicialmente, lo cual te da una flexibilidad que innerHTML no te da. De todas formas, como siempre digo en estas cosas, hay que mirar para que, cuando, como lo voy a utilizar. Y sabiendo eso, usar lo más se adapte a la situción.

  • También aveces queremos hacer cosas para lo que viene, y perdemos oportunidades en lo que estamos.

  • #1 Te ha quedad tan profundo que no he entendido nada :P

  • Hola Andrés:

    Sabes, por lo menos por ahora la propiedad innerHTML me funciona sin problemas sobre un documento enviado como application/xhtml xml; a diferencia de la popiedad outerHTML que no pasó la prueba.

  • #3 Creo que Firefox modificó su código para que esto funcionara.

  • Hola, Andrés.

    Esto que propones tú es una forma “prolija” de manipular el contenido mediante los objetos del DOM, y es lo que se debería hacer. Pero del dicho al hecho hay mucho trecho… y si ese trecho esta pavimentado con viejas PCs, peor aún.
    Y me explico:

    Supongamos que tú quieres crear una tabla graaande desde document.body, creando cada tag y cada nodo de texto. Si la PC del usuario es medianamente rápida y no está muy “cargada” de soft en memoria, todo funciona correctamente. El sufrimiento comienza con aquella PCs lentas (viejitas) o en la de aquellos usuarios que abren todos los programas que tienen instalados a un tiempo o usan aquellos que consumen mucha memoria. En ese contexto el DOM demora en crear los objetos, pero no detiene su marcha, y se da la particular situación, por ejemplo, que tu quieres crear un TD para un TR que aún no resolvió el DOM, y entonces todo se va al diablo.

    Cuando se me presentó este problema, innerHTML fue la mejor solución.

    Salu2

  • #5 Tienes razón, el tema de las máquinas antiguas es un problema para trabajar con Javascript muy pesado para el procesador, por ese motivo en la conclusión puse que depende para que aplicación estemos desarrollando debemos optar por uno u otra opción.

    Un saludo y gracias por la puntualización.

  • @JulGon: En ese caso cuando usas DOM tienes que tener cuidado en optimizarlo al máxmio posible. Por ejemplo si necesitas crear una tabla con 10 filas es mucho más óptimo crear un TR y clonarlo 10 veces que crear 10 TR mediante createElement(). Esas optimizaciones ayudan mucho.

    @Andrés: la prueba del innerHTML y XHTML la hice en Ópera, Firefox, Flock y K-meleon. Pero bueno, ojalá que sea así por mucho tiempo más (sí, sé que no es estándar, pero para lo que necesito las únicas opciones son outerHTML e innerHTML).

  • Dado que el DOM es lo correcto, una forma de evitar su complejidadd y generar una facil compatibilidad con desarrollos anteriores sería crear una función alternativa a la que se le pasara el código HTML en bruto tal como se hace con innerHTML. Esta función lo que haría sería parsear el HTML y encargarse de crear los nodos, atributos y valores correspondientes.

  • #8 Es muy buena idea. Aunque tambien puedes usar DOMTool.

    Un saludo.

  • No conocía DOMTool, y al probarlo he pensado que sería muy sencillo extenderlo para que generase automáticamente el arbol DOM, si no es que lo hace ya.

    Pero antes de ponerme a indagar se me ha ocurrido buscar en google la función html2dom, y por lo que parece ya existe código al respecto, como por ejemplo:

    http://www.phpied.com/html2dom/

    Salu2

  • Una consulta:

    En un script me interesaba modificar el valor del contenido inicial de un textarea, así que intenté de las siguientes formas (probado en IE, Ópera y Firefox)

    1) Ésta no funcionó en Ópera:

    objeto.innerHTML = “nuevo texto”;

    2) Ésta no funcionó en ninguno.

    objeto.firstChild.nodeValue = “nuevo texto”;

    3) Ésta funcionó en los 3:

    objeto.value = “nuevo texto”;

    ¿Es la tercera opción la única solución “crossbrowser”?

  • Buenas Raspu, el caso que comentas justamente no es crossbrowsing.

    Textarea solo tiene un atributo para acceder al valor y ese es value. Eso siempre te funcionará en cualquier navegador.

    El innerHTML no se puede usar para todos los elementos.

  • La verdad que cuando un argumento para justificar algo empieza con microsoft = malo, ya pierde fuerza. Aunque el resto de los argumentos pueden ser validos o no, el anterior hace tomar muy a la ligera cualquier opinion que pretenda ser seria.

    Un saludo.

  • #14 ¿Y si pensamos que algo que ha sido creado por los propietarios de el navegador más usado de internet para su único beneficio? ¿Empieza a coger valor el que sea malo?

    Generalmente en los casos en los que M$ ha metido mano siempre están perseguido por la sombra de “Ufff, lo ha hecho M$”. En este caso el ejemplo es el menos claro de todos los que se me ocurren.

    De todas lo tendré en cuenta para siguiente vez.

    Saludos

  • hola disculpa mi ignorancia en js.
    programo en php
    y queria hacer algo en js como lo que mostras ahi para generar inputs fyles
    el mConaiter es un div?
    en document.createElement(”div”), puedo poner un div?
    yo escribi esto
    function agregarimagen(){
    eDIV = document.createElement(”div”);
    eDIV.appendChild(document.createTextNode(‘hola probando’));
    document.getElementById(“imagenes”).appendChild(eDIV);
    }
    y me dice que tengo un caracter no valido.

    Gracias

  • No me contestes… Soy una bestia peluda!!!
    ya logre hacer lo que queria
    es que soy medio bruto en js

    Gracias,
    Muchas gracias por la info

Comentar

#

Me reservo el derecho de eliminar y/o modificar los comentarios que contengan lenguaje inapropiado, spam u otras conductas no apropiadas en una comunidad civilizada. Si tu comentario no aparece, puede ser que akismet lo haya capturado, cada día lo reviso y lo coloco en su lugar. Siento las molestias.