Es posible que necesitemos añadir contenido HTML a las etiquetas existentes que ya tenemos en el DOM. En el artículo anterior, vimos como añadir contenido de texto a nuestras etiquetas HTML, pero no como añadir contenido HTML. Para ello vamos a utilizar las propiedades y métodos que aprenderemos en este artículo.
Acceder al HTML del DOM
Antes de empezar, echemos un vistazo a las propiedades relacionadas que tenemos para esto:
Propiedades | Descripción |
---|---|
.nodeType | Devuelve un número del tipo de elemento. Sólo lectura. |
Contenido HTML | |
.innerHTML | Devuelve (o cambia) el contenido HTML del interior del elemento. |
.outerHTML | Idem a .innerHTML pero incluye también la propia etiqueta HTML. |
Vamos a ir viéndolas detalladamente para comprender su funcionamiento y características.
La propiedad .nodeType
La propiedad .nodeType
no tiene relación directa con este tema, pero es una forma excelente de identificar el tipo de elemento con el que estamos trabajando:
const element = document.querySelector("div");
element.nodeType; // 1
Ese valor numérico identifica el tipo de elemento con el que estamos trabajando. Los principales y más importantes, son estos tres, aunque existen algunos más que quizás veremos más adelante:
Valor | Tipo de Elemento | Descripción | Ejemplo |
---|---|---|---|
1 | Element.ELEMENT_NODE | Un elemento HTML. | <div>Hello!</div> |
3 | Element.TEXT_NODE | Un nodo de texto. | Hello! |
8 | Element.COMMENT_NODE | Un comentario HTML. | <!-- Hello! --> |
Esto nos puede servir en algunos casos donde no sabemos que tipo de elemento tenemos y queremos que actúe en consecuencia, dependiendo de su tipo.
La propiedad .innerHTML
La propiedad .innerHTML
nos permite acceder al contenido de un elemento, pero en lugar de devolver su contenido de texto como lo hace .textContent
, esta propiedad nos devuelve su contenido HTML, es decir, su marcado HTML. Esto tiene varias implicaciones que explicaremos más adelante.
Primero, un ejemplo con la diferencia entre .textContent
y .innerHTML
:
const element = document.querySelector(".message");
element.innerHTML; // "Mi nombre es <strong>Manz</strong>."
element.textContent; // "Mi nombre es Manz."
Observa que .textContent
se enfoca en obtener el contenido de texto, mientras que .innerHTML
se enfoca en el contenido HTML.
De la misma forma que .textContent
, también podemos usar .innerHTML
para modificar el contenido. Ten en cuenta que el contenido HTML suministrado a .innerHTML
se interpretará, mientras que el suministrado por .textContent
se inserta literalmente como texto:
element.innerHTML = "<strong>BOLD</strong>"; // Se lee "BOLD" (en negrita)
element.textContent = "<strong>BOLD</strong>"; // Se lee "<strong>BOLD</strong>"
Ten mucho cuidado a la hora de insertar contenido HTML utilizando
.innerHTML
puesto que si añades contenido que provenga del usuario sin revisarlo, podrían insertar HTML que realice acciones dañinas como inyección de código malicioso.
Parseo de HTML
Ten en cuenta que la propiedad .innerHTML
comprueba y parsea el marcado HTML escrito (corrigiendo si hay errores) antes de realizar la asignación.
Por ejemplo, observa el siguiente código:
const container = document.querySelector(".container");
container.innerHTML = "<strong>Manz";
container.innerHTML // "<strong>Manz</strong>"
Aunque hemos insertado el HTML incompleto con .innerHTML
, si examinamos el contenido, podemos ver que está completo. Esto ocurre porque el navegador parsea e intenta que el código HTML sea correcto en todo momento.
Esto puede provocar algunas incongruencias si el código es incorrecto o una disminución de rendimiento en porciones de código muy extensas o que hay que procesar múltiples veces.
La propiedad .outerHTML
La propiedad .outerHTML
es muy similar a .innerHTML
. Mientras este último devuelve el código HTML del interior de un elemento HTML, .outerHTML
devuelve el código HTML desde el exterior, es decir, incluyendo al propio elemento implicado:
const data = document.querySelector(".data");
data.innerHTML = "<h1>Tema 1</h1>";
data.textContent; // "Tema 1"
data.innerHTML; // "<h1>Tema 1</h1>"
data.outerHTML; // "<div class="data"><h1>Tema 1</h1></div>"
Al igual que hemos visto anteriormente, se puede utilizar .outerHTML
asignando textos para modificar su contenido. Esto puede ser muy útil para reemplazar un elemento HTML, incluido el propio elemento HTML contenedor.
Métodos modernos de HTML
En la actualidad, los navegadores están modernizando estas antiguas API, que muchas veces pueden ser confusas, añadiendo ciertas mejoras. Las propiedades como .innerHTML
permiten tanto obtener información como modificarla, cosa que a veces no es muy intuitiva para los desarrolladores.
Los nuevos métodos para manejar el DOM son los siguientes:
Propiedades | Descripción |
---|---|
.getHTML() | Alternativa moderna a innerHTML para obtener el HTML de un elemento. |
.setHTMLUnsafe(html) | Alternativa moderna a innerHTML . Permite Shadow DOM declarativo. |
.setHTML(html) | Idéntica a la anterior, pero sanitiza el contenido HTML. |
Observa que en este caso, queda claro cuales sirven para modificar el DOM y cual sólo para obtenerlo. Además, proporcionan algunas funcionalidades que no tienen los anteriores.
El método .getHTML()
El método .getHTML()
es una alternativa moderna para la propiedad .innerHTML
, sin embargo, no permite modificar el contenido HTML, sino que sólo permite obtenerlo. Esto, además de convertirlo en método en lugar de una propiedad, hace su utilización mucho más intuitiva por nuevos desarrolladores.
<div class="container">¡Hola <strong>Manz</strong>!</div>
<script>
const container = document.querySelector(".container");
console.log(container.getHTML()); // "¡Hola <strong>Manz</strong>!"
</script>
Cómo puedes ver, su utilización sería muy parecida a .innerHTML
, pero diferenciandolo bien de cuando lo utilizamos para modificar el contenido.
El método .setHTMLUnsafe()
El método .setHTMLUnsafe()
es una alternativa moderna para la propiedad .innerHTML
. Su utilización es muy similar, pero tiene como ventaja el soporte de una característica moderna llamada Shadow DOM declarativo.
Observa el siguiente fragmento de código:
const container = document.querySelector(".container");
const html = /* html */`
<div>
<template shadowrootmode="open">
<style>h1 { color: red }</style>
<h1>Interior</h1>
</template>
</div>
<h1>Exterior</h1>
`;
// Opción 1)
container.setHTMLUnsafe(html);
// Opción 2)
// container.innerHTML = html; // No funciona con Shadow DOM declarativo
<div class="container"></div>
El código anterior realiza lo siguiente:
- 1️⃣ Crea un
con código HTML con un <div>
y<template>
. - 2️⃣ Dicho código tiene un
<h1>
dentro de la plantilla (Shadow DOM) y fuera de ella (DOM normal). - 3️⃣ El método
.setHTMLUnsafe()
lo procesa y lo inserta en el interior del elemento.container
. - 🟥 Si intentamos hacer la misma operación con
.innerHTML
no funcionaría.
El texto unsafe del método es un recordatorio para el programador. Hace referencia a que el código insertado con este método puede ser inseguro, por lo que hay que tener precaución y no confiar en HTML ajeno.
El método .setHTML()
El método .setHTML()
es una versión segura de .setHTMLUnsafe()
. Este método se encarga de procesar el HTML y realizar ciertos cambios para fortalecer cuestiones de seguridad y evitar inyecciones de contenido HTML inseguro.
Sin embargo,
.setHTML()
no está implementado aún en navegadores. Sólo se ha implementado.setHTMLUnsafe()
, que es una versión moderna de.innerHTML
.