Lección 7: DOM

El uso más común de JavaScript es poder manipular el HTML, también denominado DOM, como necesitemos: Crear etiquetas nuevas, modificar existentes, borrar, cambiar textos, atributos, añadir estilos… y casi cualquier cosa que se te pase por la cabeza. El máximo exponente de estas funcionalidades lo puedes encontrar en la biblioteca JQuery, aunque debo avisarte que su uso cae en picado por la facilidades que hoy en día disponemos con el último estándar de JavaScript y el cambio de estrategia para dibujar HTML. Tradicionalmente se genera el HTML en el backend y con el frontend se modifica, mientras que ahora se tiende a recoger la información con frontend (por medio de AJAX o un JSON) y dibujar con algún Framework de renderizado (Vue, React, Angular…). Sus ventajas son numerosas, pero no es objetivo de esta lección profundizar en ese apartado.

Centremos la atención a todo lo que nos ofrece JavaScript.

Capturar un elemento

Un selector con una coincidencia

<h1 id="titulo">Curriculum vitae</h1>
const titulo = document.querySelector('#titulo');

console.log(titulo);
// <h1 id="titulo">Curriculum vitae</h1> 

Por id

<h1 id="titulo">Curriculum vitae</h1>
const titulo = document.getElementById('titulo');

console.log(titulo);
// <h1 id="titulo">Curriculum vitae</h1> 

Capturar varios elementos

Un selector con varias coincidencias

<p class="contacto">Direcciones</p>
<p class="contacto">Teléfono</p>
const contactos  = document.querySelectorAll('.contacto');

console.log(contactos);
// [<p class="contacto">Direcciones</p>, <p class="contacto">Teléfono</p>]

Por etiqueta

<p>Experiencia</p>
<p>Actitudes</p>
<p>Habilidades</p>
const parrafos = document.getElementsByTagName('p');

console.log(parrafos);
// [<p>Experiencia</p>, <p>Actitudes</p>, <p>Habilidades</p>]

Por clase

<h1 id="titulo">Curriculum vitae</h1>
<p>Experiencia</p>
<p>Actitudes</p>
<p>Habilidades</p>
<p class="contacto">Direcciones</p>
<p class="contacto">Teléfono</p>
<a href="http://papelera.com/" id="enlace">Ya le llamaremos</a>
const contactos = document.getElementsByClassName('contacto');

console.log(contactos);
// [<p class="contacto">Direcciones</p>, <p class="contacto">Teléfono</p>]

Estilos

Leer

#titulo {
  color: orange;
}
<h1 id="titulo">Curriculum vitae</h1>

Capturamos la etiqueta, que no el CSS, donde obtendremos la información.

const colorTitulo = document.querySelector('#titulo').style.color;

console.log(colorTitulo);
// orange

Añadir o sobreescribir

#titulo {
  color: orange;
}
<h1 id="titulo">Curriculum vitae</h1>
const titulo = document.querySelector('#titulo');
titulo.style.color = 'white';

console.log(titulo.style.color);
// white

console.log(titulo);
// <h1 id="titulo" style="color: white">Curriculum vitae</h1>

Borrar

Solo puedes eliminar los estilos añadidos por JavaScript. Para ello solo debes asignar como valor null.

#titulo {
  color: orange;
}
<h1 id="titulo">Curriculum vitae</h1>
const titulo = document.querySelector('#titulo');
titulo.style.color = 'white';
titulo.style.color = null;

console.log(titulo.style.color);
// orange

console.log(titulo);
// <h1 id="titulo" style="">Curriculum vitae</h1>

Atributos

Leer

<a href="http://dominio.com/" id="enlace">Otra página</a>
const miHref = document.querySelector('#enlace').getAttribute('href');

console.log(miHref);
// 'http://dominio.com/'

Modificar

<a href="http://dominio.com/" id="enlace">Otra página</a>
const enlace = document.querySelector('#enlace');
enlace.setAttribute('href', 'http://falso.com/');

console.log(enlace.getAttribute('href'))
// 'http://falso.com/'

Borrar

<a href="http://dominio.com/" id="enlace" target="_blank">Otra página</a>
const enlace = document.querySelector('#enlace');
enlace.removeAttribute('target');

console.log(enlace)
// <a href="http://dominio.com/" id="enlace">Otra página</a>

Contenido (interior de DOM)

Leer

<a href="http://dominio.com/" id="enlace">Otra página</a>
const texto = document.querySelector('#enlace').textContent;

console.log(texto)
// Otra página

Modificar

<a href="http://dominio.com/" id="enlace">Otra página</a>
const enlace = document.querySelector('#enlace');
enlace.textContent = 'Nuevo texto';

console.log(enlace.textContent);
// Nuevo texto 

Por la red encontrarás ejemplos con .innerHTML, aparentemente hará la misma funcionalidad. ¡No lo uses! Puedes crear un agujero de seguridad donde te hagan inyección de código. Y no quieres que ocurra, ¡te lo aseguro!

Borrar

Sencillamente sustituye en contendido con una cadena vacía.

<a href="http://dominio.com/" id="enlace">Otra página</a>
const enlace = document.querySelector('#enlace');
enlace.textContent = '';

console.log(enlace.textContent);
// ''

DOM

Crear

Vamos a generar una etiqueta nueva, no existente en el HTML.

Partimos del siguiente código.

<div id="articulo"></div>

1) Creamos nos la etiqueta y la guardamos en una variable para gestionarla.

const titulo = document.createElement('h1');

2) La modificamos. En este caso añadiré un contenido.

titulo.textContent = 'Mi título';

3) Lo añadiré a otro DOM existente.

document.querySelector('#articulo').appendChild(titulo);

El resultado.

<div id="articulo">
  <h1>Mi título</h1>
</div>

Borrar

Podemos usar la referencia que habíamos guardado al crearla con removeChild().

const titulo = document.createElement('h1');

document.querySelector('#articulo').removeChild(titulo);

O directamente capturar el elemento para a continuación borrar con remove().

document.querySelector('h1').remove();

Plantillas

Cuando debes generar un bloque grande de HTML que lleva tras de sí una cierta complejidad puedes simplificar tu vida creando una plantilla que a continuación clonarás para utilizar en tus iteraciones.

<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8"/>
        <title>Document</title>
    </head>
    <body>

        <nav id="nav">
            <ul id="nav__ul"></ul>
        </nav>
        
        <!-- Plantillas -->
        <template id="enlace">
            <li>
                <a href=""></a>
            </li>
        </template>

        <script>

         // Variables
         const misEnlaces = ['inicio', 'nosotros', 'contacto'];
         const navUl = document.querySelector('#nav__ul');
         // Capturo el contenido de la plantilla
         const templateLi = document.querySelector('template#enlace').content.firstElementChild;

         misEnlaces.forEach(function(enlace) {
             // Clono la plantilla
             const nuevoLi = templateLi.cloneNode(true);
             // Personalizo la información
             nuevoLi.querySelector('a').textContent = enlace;
             nuevoLi.querySelector('a').setAttribute('href', ''.concat(enlace, '.html'));
             // Incluyo a mi <ul>
             navUl.appendChild(nuevoLi);
         });

        </script>
    </body>
</html>

El resultado generado quedaría así.

<nav id="nav">
    <ul id="nav__ul">
        <li>
            <a href="inicio.html">inicio</a>
        </li>
        <li>
            <a href="nosotros.html">nosotros</a>
        </li>
        <li>
            <a href="contacto.html">contacto</a>
        </li>
    </ul>
</nav>

cloneNode(true) clona el objeto con todos sus hijos mientras que cloneNode() clona el objeto padre.

Cuidado con las referencias

¿Por qué podemos guardar un elemento del DOM en una constante y aún así es posible modificar su contenido? Porque en JavaScript se guardar las referencias al objeto, como si fuera un puntero de C. En otras palabras, guardas la dirección donde se encuentra en la memoria. Ello provoca las siguientes situaciones.

const persona1 = { edad: 42 };
const persona2 = persona1;
persona1 === persona2; // true, misma referencia

const persona3 = { edad: 42 };
persona1 === persona3; // false, diferente referencia, aunque misma data

Solución: Siempre clona, puedes usar JSON.parse(JSON.stringify(objecto)) si es un objeto o JSON. En caso de ser elementos del DOM capturados, cloneNode() como hemos visto anteriormente.

const persona4 = JSON.parse(JSON.stringify(persona1));
persona1 === persona4; // false

7-1 7-2 7-3 7-4 7-5 7-6 7-7 7-8 7-9 7-10 7-11 7-12 7-13 7-14 7-15 7-16

Esta obra está bajo una Licencia Creative Commons Atribución-NoComercial-SinDerivadas 4.0 Internacional.

Atribución/Reconocimiento-NoComercial-SinDerivados 4.0 Internacional

¿Te ayudo?

  • 1 café: ¡Gracias por el apoyo! Te ayudo a que esta web siga estando online pagando los servidores.
  • 2 cafés: Respondo a una duda en los comentarios.
  • 4 cafés: Te corrijo una actividad y te envío feedback.
Comprame un café

Comentarios

{{ comments.length }} comentarios

Nuevo comentario

Nueva replica  {{ formatEllipsisAuthor(replyComment.author) }}

Acepto la política de Protección de Datos.

Escribe el primer comentario