¿Cómo moverte entre los elementos del documento? Elemento siguiente, anterior... - Curso de JavaScript de cero a máster - Capítulo 51

Una vez más, continuamos con el manejo del DOM. Partiremos de la página HTML del capítulo anterior:

Página HTML

<!doctype html>
<html>
<head>
	<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=1" />
	<title>Curso de JavaScript</title>
	<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"
	rel="stylesheet"
	integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3"
	crossorigin="anonymous">
</head>
<body style="margin:1em">
	<div class="card text-white bg-danger mb-3" style="max-width: 18em;">
		<div class="card-header" onclick="muestraSpoiler()">Pulsa para desplegar</div>
		<div class="card-body" id="spoiler">
			<h5 class="card-title">¡Mostrando el contenido oculto!</h5>
			<p class="card-text">Este texto estaba oculto. Se ha mostrado gracias a JavaScript.
			<br>
			El diseño ya es cosa de BootStrap.</p>
		</div>
	</div>
</body>
	<script src="test.js"></script>
</html>

parentNode y nodeName

Desde JavaScript podemos obtener fácilmente el padre de un elemento con parentNode.

Código JavaScript

console.log(document.getElementById("spoiler").parentNode.nodeName);

terminal Resultado en la consola terminal

Devuelve DIV. Seleccionamos el elemento que queramos mediante su ID (aún no te he enseñado otras formas) y con parentNode selecciono su padre. Utilizo la propiedad nodeName para saber el nombre del nodo padre del elemento seleccionado por ID, que en este caso, es un DIV.

DIV
Palabra del lenguaje nº 74 encontrada.
parentNode es una propiedad de solo lectura, que devuelve el padre del nodo especificado en el árbol.
Palabra del lenguaje nº 75 encontrada.
nodeName devuelve el nombre del nodo actual en forma de string.

De hecho, puedes comprobar que se obtiene el elemento padre quitando nodeName:

Código JavaScript

console.log(document.getElementById("spoiler").parentNode);

terminal Resultado en la consola terminal

<div class="card text-white bg-danger mb-3" style="max-width: 18em;">...</div>

Esto lo puedes utilizar para muchas cosas. Una de ellas, es en un condicional if, para que se haga una cosa diferente en el caso de que el elemento sea una cosa u otra.

Código JavaScript

let elementoSpoiler = document.getElementById("spoiler").parentNode.nodeName;

if (elementoSpoiler == "DIV") {
	console.log("El padre es una etiqueta div.");
} else {
	console.log("El padre no es una etiqueta div.");
}

terminal Resultado en la consola terminal

El padre es una etiqueta div.

nextSibling y previousSibling

Algo muy útil es poder obtener los nodos vecinos de un elemento, no solo el padre.

Palabra del lenguaje nº 76 encontrada.
nextSibling obtiene el nodo del DOM siguiente (next) a partir de un nodo dado.

¿Cuál es el siguiente nodo al <head> en la página html de arriba?

Código JavaScript

console.log(document.head.nextSibling);

terminal Resultado en la consola terminal

Podríamos pensar que el siguiente nodo al <head> es lógicamente el <body>, pero recuerda, que cada salto de línea que hay, genera nodos #text.

#text

¿Qué pasa si borramos el salto de línea y dejamos el <head> pegado al <body>?

Etiquetas HTML

</head><body style="margin:1em">

terminal Resultado en la consola terminal

<body style="margin:1em">...</body>

Como podrás deducir por el nombre, previousSibling hace lo contrario.

Palabra del lenguaje nº 77 encontrada.
previousSibling obtiene el nodo del DOM anterior (previous) a partir de un nodo dado.

Código JavaScript

console.log(document.body.previousSibling);

terminal Resultado en la consola terminal

Si tenemos un salto de línea entre el <head> y el <body>, lo que va a hacer es devolvernos un nodo #text. En cambio, supongamos que lo tenemos "pegado" como en el ejemplo anterior.

<head>...</head>

Claro, así, hay un problema para utilizar esto, ya que todos los nodos de elementos HTML deberán estar pegados literalmente, como esto:

Página HTML

<!doctype html><html><head>...

No se puede trabajar de esta forma. Afortunadamente hay una solución excelente. Aquí está:

nextElementSibling y previousElementSibling

Para omitir los nodos como #text y fijarse solo en elementos HTML (etiquetas), podemos utilizar nextElementSibling y previousElementSibling.

Palabra del lenguaje nº 78 encontrada.
nextElementSibling obtiene el siguiente nodo a partir de uno dado. Se omiten los nodos #text y #comment.

Código JavaScript

console.log(document.head.nextElementSibling);

terminal Resultado en la consola terminal

Se obtiene el siguiente elemento al <head>.

<body style="margin:1em">...</body>
Palabra del lenguaje nº 79 encontrada.
previousElementSibling obtiene el nodo anterior a partir de uno dado. Se omiten los nodos #text y #comment.

Código JavaScript

console.log(document.body.previousElementSibling);

terminal Resultado en la consola terminal

Se obtiene elemento anterior al <body>.

<head>...</head>

Etiquetas HTML

<body style="margin:1em">
	<div class="card text-white bg-danger mb-3" id="divPrincipal" style="max-width: 18em;">
		<div class="card-header" onclick="muestraSpoiler()">Pulsa para desplegar</div>
		<div class="card-body" id="spoiler">
			<h5 class="card-title">¡Mostrando el contenido oculto!</h5>
			<p class="card-text">Este texto estaba oculto. Se ha mostrado gracias a JavaScript.
			<br>
			El diseño ya es cosa de BootStrap.</p>
		</div>
	</div>
</body>

Fijémonos ahora en el <body> del doumento HTML. Le he añadido al <div> de la línea 2 un ID.

¿Qué ocurrirá aquí si utilizo nextElementSibling con el id="divPrincipal"?

Veamos que ocurre.

Código JavaScript

console.log(document.getElementById("divPrincipal").nextElementSibling);

terminal Resultado en la consola terminal

¿Es esto lo que esperabas?

<script src="test.js"></script>

Analicemos el DOM:

Árbol del DOM

Si vemos el árbol del <div>, el siguiente elemento (omitiendo el #text) es <script>.

Estas guías laterales son muy buena referencia para trabajar, nos dan una perspectiva muy útil.

Todo lo que está anidadado dentro de un elemento, no se accede de esta forma.

Por lo tanto, ¿Cómo se accede por ejemplo al siguiente elemento del primer <div> anidado?

Puesto que aún solo te he enseñado por ID, le vamos a dar uno al <div> en cuestión.

Etiquetas HTML

<div class="card-header" onclick="muestraSpoiler()" id="muestraSpoiler">Pulsa para desplegar</div>

Código JavaScript

console.log(document.getElementById("muestraSpoiler").nextElementSibling);

terminal Resultado en la consola terminal

<div class="card-body" id="spoiler"></div>

Ves practicando todo esto hasta que lo acabes de entender. Tampoco te mates a hacer pruebas si te cuesta. Seguiremos viendo más ejemplos.