JavaScript y el DOM

¿Para qué tenemos JavaScript?

(en el browser)

  • Agregar contenido
  • Modificar contenido
  • Eliminar contenido
  • Cambiar estilos (CSS)
  • Reaccionar a diferentes eventos (ej: el usuario clickea un botón)
  • etc

La razón por la que aparece JavaScript es para que podamos interactuar con los diferentes sitios web

¿Cómo hago para interactuar, usando JavaScript, con un sitio web?

Document Object Model (DOM)

  • Representa la estructura y los elementos de un sitio web (documento)
  • Lo crea el browser cuando cargamos un sitio
  • Nos provee de una API (interfaz) para modificarlo
  • A cada uno de sus elementos los vamos a llamar nodos

¿Qué es el DOM?

Document

Cuando hablamos de documento, estamos haciendo referencia al archivo HTML que estamos viendo en el browser

Object

Cada uno de los elementos o componentes de nuestro sitio (tags de HTML, texto, etc) van a estar representados en el DOM mediante un objeto

Model

El DOM es un modelo que representa la estructura, los elementos (y la relación entre éstos) de un sitio web

Nos provee de una API

  • Y acá es donde aparece JavaScript: es el lenguaje que vamos a usar para interactuar con los sitios web, a través del DOM
  • Tenemos disponibles diferentes propiedades y métodos que podemos usar para interactuar con el HTML

Nodos

  • Cada elemento del DOM es un nodo (incluye tags, texto, atributos, comentarios, etc)
  • Pueden tener descendientes (children), hermanos (siblings), antecesores (parent)
  • Tenemos diferentes tipos de nodos, pero los que más vamos a usar son Element y Text

Nodos: props y métodos útiles

  • Node.nodeType
  • Node.nodeName
  • Node.hasChildNodes()
  • Node.childNodes
  • Node.parentNode
  • Node.cloneNode(true || false)

Para más detalles, leer el artículo

What, exactly, is the DOM?

 

⚡️

document

⚡️

document.head;
document.body;

⚡️

if (document.body.nodeType === document.ELEMENT_NODE) {
  console.log("Body is an element node!");
} else {
  console.log("Body is a textual node!");
}

⚡️

document.getElementById

⚡️

document.getElementsByClassName

⚡️

document.getElementsByTagName

⚡️

for (let i = 0; i < bookLists.length; i++) {
  console.log(bookLists[i]);
}

HTMLCollection

  • Se parece a un array, pero no es un array
  • Sólo puede contener nodos de tipo Element
  • Si queremos usar métodos de array, como forEach, primero tenemos que convertir la HTMLCollection a un array de verdad
  • Puedo acceder a los elementos usando un índice

⚡️

bookLists = Array.from(bookLists);

bookLists.forEach(list => console.log(list));

⚡️

document.querySelector

⚡️

document.querySelectorAll

NodeList

  • Se parece a un array, pero no es un array
  • Puede contener nodos de cualquier tipo
  • Podemos usar forEach
  • Puedo acceder a los elementos usando un índice

HTMLCollection vs NodeList

  • Contienen diferentes tipos de nodos (HTMLCollection sólo contiene nodos de tipo Element mientras que NodeList puede contener nodos de cualquier tipo)
  • Diferentes propiedades y métodos

⚡️

const authors = document.querySelectorAll('#fantasy .author');

authors.forEach(author => console.log(author));

tl;dr

¿Y cómo hago para modificar el contenido de un nodo?

textContent

  • Propiedad que tienen todos los nodos (cada uno de los elementos del DOM)
  • Me sirve para obtener el contenido de tipo texto de un nodo y poder modificarlo

⚡️

authors.forEach(author => console.log(author.textContent));

⚡️

authors.forEach(author => author.textContent = "Ricky Fort");

⚡️

authors.forEach(author => author.textContent += ", Ricky Fort");

innerText

  • Similar a textContent, pero con algunas diferencias
  • Propiedad que tienen sólo los nodos de tipo Element
  • Me sirve para obtener el contenido de tipo texto y poder modificarlo
  • Sólo accede al texto visible (textContent muestra todo)

getAttribute

  • Retorna el valor de un atributo dado para el nodo al que se aplique
  • Algunos atributos pueden ser accedidos directamente como propiedades (id, href, etc)

⚡️

// Show href attribute of the first link
console.log(document.querySelector("a").getAttribute("href"));

// Show ID attribute of the first list
console.log(document.querySelector("ul").id);

// Show href attribute of the first link
console.log(document.querySelector("a").href);

hasAttribute

  • Método que sirve para chequear la existencia de un atributo en un nodo

⚡️

if (document.querySelector("a").hasAttribute("target")) {
  console.log("The first link has a target attribute.");
} else {
  console.log("The first link does not have a target attribute.");
}

classList

  • Propiedad que sirve para obtener la lista de clases de un elemento
  • Algunos métodos útiles de classList: add, remove, toggle

Hagamos ejercicios!

¿Y si quiero cambiar el HTML de un nodo?

innerHTML

  • Propiedad que tienen sólo los nodos de tipo Element
  • Me sirve para obtener el HTML un nodo y poder modificarlo

⚡️

const booksLists = document.querySelectorAll(".book-list");

booksLists[0].innerHTML = "<p>There are no books in this category</p>";

Más ejercicios!

Ejercicio: eliminar nodo

Traversing the DOM

(o sea recorrerlo)

Desplazándonos por el DOM

  • La idea es movernos de un nodo hacia otro
  • Podemos movernos en diferentes direcciones: hacia arriba (parent), hacia abajo (children), de costado (siblings)
  • Si sé hacia dónde quiero moverme, es más eficiente que hacer una búsqueda completa (ej: usando document.querySelector)

Desplazándonos hacia abajo ⬇️

element.querySelector
  • Buscamos un nodo específico a partir de otro
  • Esto es más rápido que hacer una búsqueda completa en document
  • También aplica para querySelectorAll
<div class="component">
  <h2 class="component__title">Component title</h2>
</div>
const component = document.querySelector('.component');
const title = component.querySelector('.component__title');
element.querySelector
childNodes
  • Es una propiedad que nos permite obtener los descendientes directos de un nodo
  • Retorna una NodeList
<ul class="list">
  <li><a href="#">Link 1</a></li>
  <li><a href="#">Link 2</a></li>
  <li><a href="#">Link 3</a></li>
  <li><a href="#">Link 4</a></li>
  <li><a href="#">Link 5</a></li>
</ul>
const list = document.querySelector('.list');
const listItems = list.childNodes;
childNodes

Desplazándonos hacia arriba ⬆️

parentNode
  • Es una propiedad que nos permite obtener el nodo antecesor
  • Retorna una NodeList
const author = document.querySelector('.author');
const listItems = author.parentNode;
const list = listItems.parentNode; 
// también puedo encadenar
author.parentNode.parentNode;
parentNode
closest
  • Permite encontrar un elemento que se encuentre múltiples niveles por encima del nodo actual (el ancestro más cercano)
  • Empieza a buscar desde el nodo actual y va hacia arriba, hasta llegar a document. Se detiene cuando encuentra un elemento que matchee con el selector y lo devuelve
closest
<ul class="list">
  <li><a href="#">Link 1</a></li>
  <li><a href="#">Link 2</a></li>
  <li><a href="#">Link 3</a></li>
  <li><a href="#">Link 4</a></li>
  <li><a href="#">Link 5</a></li>
</ul>
const firstLink = document.querySelector('a');
const list = firstLink.closest('.list');
children & parentElement
  • Propiedades análogas a childNodes y parentNode, pero sólo aplican a nodos de tipo Element
  • Retornan HTMLCollection

Desplazándonos lateralmente ⬅️ ➡️

(entre nodos que estén al mismo nivel)

nextSibling
  • Nos permite obtener el nodo siguiente, al mismo nivel (hermano)
nextSibling
<ul class="list">
  <li><a href="#">Link 1</a></li>
  <li><a href="#">Link 2</a></li>
  <li><a href="#">Link 3</a></li>
  <li><a href="#">Link 4</a></li>
  <li><a href="#">Link 5</a></li>
</ul>
const firstListItem = document.querySelector('li');
const secondListItem = firstListItem.nextSibling;
previousSibling
  • Nos permite obtener el nodo anterior, al mismo nivel (hermano)
previousSibling
<ul class="list">
  <li><a href="#">Link 1</a></li>
  <li><a href="#">Link 2</a></li>
  <li><a href="#">Link 3</a></li>
  <li><a href="#">Link 4</a></li>
  <li><a href="#">Link 5</a></li>
</ul>
const secondListItem = document.querySelectorAll('li')[1];
const firstListItem = secondListItem.previousSibling;
nextElementSibling & previousElementSibling
  • Propiedades análogas a nextSibling y previousSibling, pero sólo aplican a nodos de tipo Element

Javascript y el DOM

By Nicolás Quiroz

Javascript y el DOM

  • 140