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.
¿Me ayudas?
No te sientas obligado a realizarme una donación, pero cada aportación me ayuda a mantener el sitio en activo para que continúe existiendo y me motiva a continuar creando nuevo contenido.

- 1 café: Se mantiene el dominio durante 4 meses.
- 2 cafés: Se liquida 1 mes del Servidor Web.
- 3 cafés: Se paga 1 mes de Newsletter.
Comentarios
Nuevo comentario
Nueva replica {{ formatEllipsisAuthor(replyComment.author) }}
Escribe el primer comentario
{{ comments.length }} comentarios