Introducción al Modelo de Objetos de Documento (DOM)
Revisa la recomendación W3C DOM2 standard.El primer paso es crear un objeto nodo del tipo que quieras utilizar de
entre document.createElement(), document.createAttribute() o
document.createTextNode(). Para atributos, sin embargo, probablemente
querrás crear un nodo elemento y asignárselos a éste
directamente (recalcar que IE, hasta la versión 5.5, no soporta
createAttribute()).
Trabajando con Nodos de Texto
Vamos a empezar con un nodo de texto. Abajo hay un código de ejemplo mostrando cómo crear un nodo de texto y asignarle un valor.
var myTextNode = document.createTextNode("my text");
Ahora tienes un nodo de texto. Pero no es parte del árbol del documento. Para hacer que aparezca en la página, necesitas agregarlo como un hijo de un nodo existente dentro del árbol. Como los nodos de texto no pueden tener nodos hijos, no puedes agregárselo a otro nodo de texto. Los nodos atributos no son parte del árbol del documento, por lo que tampoco puedes agregarles nuevos nodos. Ésto nos deja sólo los nodos de tipo elemento.
Puesto que los nodos elemento pueden tener varios hijos, son proporcionados unos cuantos métodos diferentes que te permiten especificar dónde añadir los nuevos nodos entre sus hijos existentes. Esto se puede ilustrar mejor con un ejemplo.
Aquí, el método appendChild() para agregar
nuevo texto a un elemento párrafo. También te permite remover
el último nodo añadido usando el método removeChild()
:
Initial text within a paragraph element.
Add Text Node | Remove Text Node
Ahora echémosle un vistazo al código:
<p id="sample1">Initial text within a paragraph element.</p>
... code to add a text node ...
var text = document.createTextNode(" new text " + (++counter1));
var el = document.getElementById("sample1");
el.appendChild(text);
... code to remove the last child node ...
var el = document.getElementById("sample1");
if (el.hasChildNodes())
el.removeChild(el.lastChild);
Agregar texto es fácil, el código crea un nuevo nodo de
texto, localiza el nodo del elemento párrafo y llama a appendChild()
para insertarlo al final de su array childNodes. Una variable
contador global es utilizada en el propio texto para que puedas distinguir
cada nuevo nodo en lo que muestra el navegador.
Quitar texto es casi tan fácil, usando una llamada a removeChildNode()
. La única diferencia está en la adición de un nodo
de referencia, cuál de los hijos del elemento debe ser removido. Aquí
utilizamos la propiedad lastChild del elemento que siempre apunta
al último nodo de la matriz de childNodes del elemento.
Nótese que también va a eleiminar el texto inicial escrito
inicialmente en el código de la etiqueta P si éste es el único
hijo.
Resaltar también el uso del método hasChildNodes()
que simplemente devuelve true o false para indicar
si el nodo dado tiene algún hijo actualmente. Aquí se ha utilizado
para prevenirt un error por llamar removeChild cuando no le
queda ningún hijo.
Normalizando y Partiendo Nodos de Texto
En ejemplo anterior, los nuevos nodos de texto se han añadido como hijos independientes. Pero si has escrito texto adicional en el marcado HTML,
<p id="sample1">Initial text within a paragraph element. new text 1
new text 2 new text 3</p>
aparecería en el DOM como un sólo nodo hijo de texto del elemento párrafo. En otras palabras, el árbol de nodos producido añadiendo contenido dinámicamente aparecería diferente del árbol de nodos que resultaría si dicho contenido hubiese sido incluido en el código HTML estático.
Ésto puede o no ser deseable dependiendo de lo que estés intentando hacer. En algunos casos puedes querer combinar nodos de texto para hacer que el árbol refleje como si el nuevo contenido, añadido dinámicalmente, fuese una parte del código original HTML, estático.
El método normalize() nos proporciona dicha funcionalidad.
Llamándolo sobre un elemento "limpiará" el árbol de
nodos, combinando cualquiera de los nodos de texto adyacentes y eleiminando
cualquiera de los que estén vacios.
normalize
. El ejemplo de abajo no funcionará apropiadamente en este navegador.
IE 6.0, sin embargo, si lo soporta (aunque no funcionase en la versión
beta). Para demostrarlo, aquí está el mismo ejemplo utilizado anteriormente pero con links adicionales proporcionados para normalizar el elemento párrafo y mostrar su número actual de hijos.
Initial text within a paragraph element.
Add Text Node | Remove Text Node | Show Child Node Count | Normalize Element
Puedes ver que mientras que añades texto, el número de nodos hijos aumenta pero que, en cuanto normalizas el párrafo, se combinan en un único nodo de texto. Aquí está el código para los links adicionales:
... normalize element ...
el = document.getElementById("sample2");
el.normalize();
... show number of child nodes ...
el = document.getElementById("sample2");
alert(el.childNodes.length);
También puedes partir un nodo de texto en dos separados usando
el método splitText(). Ésto puede resultar útil
si quieres alterar dinámicamente una sóla palabra o frase o
insertar un elemento en una línea de texto.
Vamos con otro ejemplo. Esta vez, el link remove va a borrar el primer hijo del párrafo. Inicialmente, este va a ser la frase entera. Pero si utilizas separate link primero, va a separar la primera palabra en el texto y subsequentemente 'remove' va a borrar sólo esa palabra. El link 'reset' te permite empezar de nuevo.
Initial text within a paragraph element.
Separate First Word | Remove First Text Node | Reset
Y aquí está el código para cada función:
... split at first word ...
el = document.getElementById("sample3");
if (el.hasChildNodes()) {
text = el.firstChild;
i = text.nodeValue.indexOf(" ");
if (i >= 0)
text.splitText(i + 1);
}
... remove first text node ...
el = document.getElementById("sample3");
if (el.hasChildNodes())
el.removeChild(el.firstChild);
... reset the example ...
el = document.getElementById("sample3");
while (el.hasChildNodes())
el.removeChild(el.firstChild);
text = document.createTextNode(
"Initial text within a paragraph element.");
el.appendChild(text);
Algunas notas aquí. El nodeValue de un nodo de texto
es simplemente una cadena. El método splitText() method
espera un valor inicial que le diga pro dónde rompe el texto.El método
del objeto string indexOf() es utilizado para encontrar el primer
espacio en blanco en el texto y pasárselo a splitText().
En segundo lugar, el código de reset simplemente borra todos los nodos hijos del párrafo original y entonces vuelve a agregar el texto original como un sólo nodo.