Ya mencionamos que en Javascript y en muchos lenguajes dirigidos a manipular clases son los objetos quienes agrupan métodos -acciones– y propiedades con valores. Por lo que al modificar elementos HTML accederemos a los objetos de la API DOM.
SELECCIONAR ELEMENTOS HTML DESDE EL DOM
Los selectores querySelector() y querySelectorAll son dos métodos comunes para seleccionar elementos HTML a partir de su clase o id.
ESTRUCTURA PARA EJEMPLOS
Si bien el objeto DOM contiene en su estructura los elementos HTML, usaré JS para accederlos. En adelante lo combinaré con la sintaxis HTML solo para demostración. Recomiendo conocer la sintaxis HTML al detalle –y cómo vincular archivos HTML y JS– mediante tutoriales audiovisuales o con bibliografía técnica en caso de seguir con el estudio del DOM.
<!doctype html>
<html>
<head>
<!-- Permite mostrar caracteres tildados -->
<meta charset="UTF-8">
<script>
// Aquí el código JS que accede a los elementos HTML
</script>
</head>
<body>
<!-- Aquí los elementos HTML -->
</body>
</html>
Selector querySelector()
Ambos selectores 'controlan' un elemento HTML al ubicarlo según su nombre de etiqueta (por ejemplo "h1", "p"), su <id="">
o su <class="">
Sin embargo, cuando cada uno de estos selectores es conectado con el objeto, entonces se convierten en métodos que devolverán un resultado.
En HTML
<h1 class="titulo"> Aquí va el titulo </h1>
En Javascript
// Obtener el primer elemento "h1"
let elem = document.querySelector("h1");
console.dir(elem);
// h1.titulo
Ambos códigos devolverán –solo en consola– dos valores: la etiqueta 'h1'; y el nombre de la clase "titulo".
De igual forma, se puede acceder a un elemento HTML que contenga un identificador ID.
En HTML
<h3 class="nada"> ... </h3>
<h3 class="nada"> ... </h3>
<h3 id="subtitulo"> Elemento ID</h3>
Javascript
/* Obtener el elemento con ID */
let elem = document.querySelector("#subtitulo");
console.dir(elem);
// h3#subtitulo
En otro ejemplo seleccionamos los elementos según el nombre identificador id o la clase.
En HTML
<h3 class="cosaClase"> ... </h3>
<h3 id="cosaIdentificador"> ... </h3>
Javascript
let elem = document.querySelector(".cosaClase");
console.dir(elem);
// Consola muestra:
// h3.cosaClase
let elem2 = document.querySelector("#cosaIdentificador");
console.dir(elem2);
// Consola muestra:
// h3#cosaIdentificador
RECORDAR
Cada identificador en los querySelector() va agrupado en paréntesis y comillas ("..."). Ejemplo:
...querySelector("#identificadorClase");
...querySelector(".identificadorId");
Selector querySelectorAll()
Selecciona todos los elementos según el identificador de la clase de esos elementos:
En HTML
<h3 class="titulo"> Aquí va primer titulo </h3>
<h3 class="titulo"> Aquí va segundo titulo </h3>
<h3 class="titulo"> Aquí va tercer titulo </h3>
Javascript
/* Obtener todos los elementos con
el identificador de clase "titulo" */
let elem = document.querySelectorAll(".titulo");
console.dir(elem);
/*
0:h3.titulo
1:h3.titulo
2:h3.titulo
length:3
*/
Como se demostrará en las siguientes secciones, es a partir de la selección de los elementos HTML desde la API DOM que podremos alterarlos y manipularlos.
MANIPULAR ELEMENTOS USANDO EL DOM
Manipular elementos HTML desde el DOM significa explorarlos, seleccionarlos, añadir nuevos elementos, añadirles estilo, acciones interactivas y nuevos atributos junto con sus valores, entre otros.
PROPIEDAD BODY
Para Lars Svekis y van Putten [5] la propiedad body
contiene todo lo que se halla dentro de los tags <body> ... </body> del documento HTML:
Javascript
/* Escribiendo en consola */
console.dir(document.body);
/* El Inspector mostrará docenas
de propiedades y valores del objeto body
:
body
aLink:""
accessKey:""
ariaAtomic:null
ariaAutoComplete:null...
*/
/* Otro ejemplo en una variable */
var seleccion = querySelection(document.body);
PROPIEDAD CHILDREN
Obtiene elementos HTML anidados uno dentro de otros. El primer padre es document.body
y luego, cada propiedad children
apuntará al elemento inmediato (el hijo) de cada padre. Ejemplo:
En HTML
<!-- Padre -->
<div id="Padre1"> ...
<!-- Hijo y padre -->
<div id="hijo1">
<!-- Hijo y padre -->
<div id="Padre2">
<!-- Solo hijos -->
<div id="Hijo2A">..</div>
<div id="Hijo2B">..</div>
</div>
</div>
</div>
Javascript
/* Selecciona SOLO el hijo1 */
console.dir(document.body
.children.Padre1
.children.hijo1);
// -> Muestra div#hijo1
/* Selecciona SOLO el padre1 */
console.dir(document.body
.children.Padre1);
// -> Muestra div#Padre1
/* Selecciona SOLO el hijo2A */
console.dir(document.body
.children.Padre1
.children.hijo1
.children.Padre2
.children.Hijo2A);
// -> Muestra div#Hijo2A
- La secuencia es:
...body.padre.children.hijo
- Un elemento padre es cada identificador que agrupa otro elemento.
- Cada
childnode
debe inicia con un padre... - ...y luego de eso apunta al hijo.
- Recordar: muchas veces un hijo también es padre de otro elemento.
PROPIEDAD CHILDNODES
Permite en breve determinar un arreglo (array) cuyo índice dado apuntará al elemento HTML a seleccionar.
En HTML
<!-- OJO CON ESTO: El espacio de arriba es un nodo [0] #text.
Este comentario es un nodo [1] #comment y el espacio
siguiente antes del div es otro nodo [2] #text -->
<div id="Padre1"> ... </div>
Javascript
/* Seleccionar Padre1.
Según los elementos de arriba, el nodo con id 'Padre1'
corresponde al índice [3] */
console.dir(document.body
.childNodes[3]);
//-> Muestra div#Padre1
Solo en caso de que se eliminen los espacios vacíos y los comentarios, el nodo [0] sería entonces el elemento Padre1.
IMPORTANTE DIFERENCIA
La propiedad childNodes
devuelve un objeto nodeList
, accedido mediante índice numérico [..]. Este objeto puede ser un espacio de caracter vacio, comentarios y los propios elementos. En otras palabras, todos esos nodos contemplan un índice.
Por otro lado, la propiedad children
solo devuelve elementos HTML (no toma en cuenta espacios vacios y comentarios).
Para mostrar el índice de los nodos y su cantidad:
En HTML
<div id="Afuera">
<div id="dentro"></div>
</div>
Javascript
let todoEldiv = document.getElementById("Afuera");
let mostrar = todoEldiv.childNodes;
console.dir(mostrar);
//->
/* NodeList(3)
0: text
1: div#dentro
2: text
length: 3
[[Prototype]]: NodeList */
Para mostrar las etiquetas y los elementos nodos de un body
en tiempo real:
En HTML
<!-- Cada comentario es un nodo #comment -->
<!-- Cada salto de linea es un nodo #text -->
<h1> </h1>
<h2> </h2>
<p> </p>
<p>Los elementos son:</p>
<p id="demo"></p>
Javascript
// Se llama a todos los nodos
const listaNodos = document.body.childNodes;
// Para guardar todo lo hallado
let loHallado = "";
// Recorre todos los nodos mediante indice
for (let i = 0; i < listaNodos.length; i++) {
/* Ojo con el atributo nodeName.
Este muestra el nombre del nodo en tiempo real */
loHallado = loHallado + listaNodos[i].nodeName + "
";
}
// Muestra
document.getElementById("demo").innerHTML = loHallado;
/* En la pantalla se muestra:
Los elementos son:
#text, #comment, #text, #comment, #text, H1, #text, H2, #text, P,
#text, P, #text, P, #text, SCRIPT */
Para dar estilo a un elemento seleccionado según su índice:
En HTML
<div id="agrupador"><!-- [0]-->
<p>Soy [1]</p>
<!-- [2]-->
<p>soy [3]</p>
</div>
Javascript
document.getElementById("agrupador")
.childNodes[3].style.backgroundColor = "yellow";
// Solo 'soy [3]' se muestra con fondo amarillo
Para determinar lo que está antes de un elemento apuntado:
En HTML
<div id="agrupador"><!-- [0]-->
<p>Soy [1]</p>
<!-- [2]-->
<p>soy [3]</p>
</div>
Javascript
var elem = document.getElementById('holiSpan')
.previousElementSibling;
document.write('Lo que esta arriba de span:
');
/* Mientras que 'elem' sea true. O sea,
mientras tenga un dato válido como mínimo */
while (elem) {
/* Recordar nodeName: permite mostrar
la etiqueta de cada elemento apuntado */
document.write('' + elem.nodeName + ' ');
elem = elem.previousElementSibling;
}
document.write('');
/*
En la pantalla se muestra: div, div, p
Lo que esta arriba de span: DIV, H4
*/
SELECCIONAR Y CAMBIAR PROPIEDADES DE ELEMENTOS COMO OBJETOS
Para manipular elementos HTML desde el API DOM en JS, se direcciona un elemento de la siguiente forma:
En HTML
<h1> aaa </h1>
<p id="saludos"> bbb </p>
Javascript
/* Solo apunta al contenido agrupado
entre los signos de apertura y cierre
del elemento HTML. Aún no hay cambios. */
document.body.children.saludos;
PROPIEDAD INNERTEXT
Apunta a todo el contenido únicamente textual que está agrupado entre los tags de apertura y cierre de un elemento HTML. Así mismo, mostrará cualquier cambio que sea en un texto.
El siguiente ejemplo apunta solo a un elemento de texto y al cambio –también textual– a ejecutar en él:
En HTML
<!-- La etiqueta H1 con el id 'saludos' tiene un contenido -->
<h1 id="saludos"> ... </h1>
<p id="textito"> ... </p>
Javascript
/* Ahora la etiqueta H1 con el id 'saludos'
mostrará la palabra Holi!! */
document.body.children.saludos.innerText = "Holi!!";
// + + +
/* Ahora la etiqueta p con el id "textito" muestra la palabra
Holi!! */
document.body.children.textito.innerText = "Holi!!";
PROPIEDAD INNERHTML
La propiedad innerHTML
altera textos y elementos HTML –con sus tags–. Así, para reemplazar un elemento HTML por otro nuevo elemento HTML con nuevos tags (en este caso, con tags <h1></h1>y <i>...</i>) :
Javascript
/* Un nuevo elemento con nuevos tags HTML se agrega
en reemplazo al elemento con el ID "textito" */
document.body.children.textito.innerHTML=
"<h1><i>Nuevo titulo</i></h1>";
ACCEDER A ELEMENTOS DESDE EL ID
El método getElementById()
devuelve un elemento apuntando a un id único –no se repite en en ningún lado del mismo documento–.
En HTML
<h1> Ejemplo </h1>
<div id="uno" class="ejemplo"> aaa </div>
<div id="dos" class="ejemplo"> bbb </div>
<div id="tres" class="algo"> ccc </div>
Javascript
console.dir( document.getElementById("two") );
//-> div#dos.ejemplo
ACCEDER A ELEMENTOS DESDE EL NOMBRE DEL TAG (tag name)
Apuntar a un elemento HTML por su nombre de tag podría dar como resultado un tipo de dato arreglo o una lista de nodos (pueden haber más de un elemento con el mismo nombre de tag, como el tag <div>...</div>) como en el siguiente ejemplo:
Javascript con el mismo bloque HTML dado arriba
// Apunta a todos los elementos de tag 'div'
// Ojo con ElementS –termina en 's'-
console.dir(document.getElementsByTagName("div"));
// La consola muestra:
/* HTMLCollection(3)
0: div#uno.ejemplo
1: div#dos.ejemplo
2: div#tres.algo
dos: div#dos.ejemplo
tres: div#tres.algo
uno: div#uno.ejemplo
length: 3 */
Por eso es útil apuntar a elementos ID únicos, y no a nombres de tag (que pueden ser cientos de elementos).
APUNTAR A ELEMENTOS SEGÚN SU TAG Y SU INDICE
Mediante el método getElementsByTagName
–OJO, es ElementS– y mediante el métodos item()
.
En HTML
<div id="a" class="letra"> aaa </div>
<div id="b" class="letra"> bbb </div>
<p id="num" class="numero"> 222 </div>
<p id="num1" class="numero"> 333 </div>
Javascript
/* Ubicar el 'div' con indice cero */
console.dir(
document.getElementsByTagName("div").item(0)
);
// -> div#a.letra
/* Ubicar el 'p' con indice cero */
console.dir(document.getElementsByTagName("p").item(1));
// -> p#num1.numero
Para apuntar a un elemento con el ID dado, usar también namedItem("..")
. Por ejemplo:
En HTML
<p id="xx" class="numero"> 222 </div>
<p id="yy" class="numero"> 333 </div>
Javascript
/* Ubicar el 'div' con el ID 'num' */
console.dir(
document.getElementsByTagName("p").
namedItem("identificador_ID"));
// p#num.numero
/* Cuando se invoca con console.log(); */
console.log(
document.getElementsByTagName("p").namedItem("xx"));
/* -> <p id="xx" class="numero"> 222 </p> */
Para apuntar a todos los elementos de un mismo tipo (por ejemplo, solo elementos <p>) se usa como argumento de getElementsByTagName("...")
el nombre de la etiqueta a apuntar. El resultado será un HTMLCollection
de todos los elementos <p> sea cual fuere su ID o su CLASS:
- ERROR (Omitir la S):
getElementByTagName("...")
- CORRECTO (Con la S):
getElementsByTagName("...")
En HTML
<!-- Todos son elementos <p>-->
<!--Sin ID o CLASS-->
<p> .. </div>
<!-- Sin CLASS-->
<p id="bb"> .. </div>
<!-- Sin ID-->
<p class="numero"> .. </div>
Javascript
/* Apuntar a todos los elementos <p>*/
console.log(
document.getElementsByTagName("p"));
/* HTMLCollection(3)
0: p#aa.numero
1: p#bb.numero
2: p#cc.numero
aa: p#aa.numero
bb: p#bb.numero
cc: p#cc.numero
len
APUNTAR A ELEMENTOS POR EL NOMBRE DE CLASE (CLASS NAME)
En HTML
<!-- Elementos con igual clase -->
<p class="xx" id="holi"> .. </div>
<p class="xx" id="lali"> .. </div>
<p class="zz"> .. </div>
Javascript
/* Apuntar a elementos de clase 'xx' */
console.log(
document.getElementsByClassName("xx"));
/* -> HTMLCollection(2)
0: p#holi.xx
1: p#lali.xx
holi: p#holi.xx
lali: p#lali.xx
length:2
* Notar que el elemento 'p' de clase 'zz' no es mostrado. */