Aprende Javascript con MentoringJS - Step 7
Hola chicos! En este articulo os voy a enseñar a modificar el DOM sin la necesidad de tener que utilizar jQuery.
Para modificar nuestro DOM vamos a tener que hacer una de las siguientes cosas:
Este es el primer paso que debemos hacer antes de modificar nuestro DOM. Seleccionaremos un o varios elementos y podremos añadir oyentes de eventos, modificar clases, etc etc…
Solo hay 2 métodos:
Puedes seleccionar un elemento por su ID, CLASS o etiqueta.
document.querySelector('div #id1');
// solo selecciona las div que tengan un ID="id1"
```javascript
let elementoInterior = document.querySelector('.contenedor elementoInterior');
// Esto selecciona un elemento interior que este dentro de una CLASS .contenedor
Si ya tienes eleccionado un elemento con querySelector puedes usar ese elemento para realizar otra llamada a querySelector:
let contenedor = document.querySelector('.contenedor');
let elementoInterior = contenedor.querySelector('.elementoInterior');
// En la primera linea seleccionamos un elemento con CLASS=".contenedor"
// En la siguiente linea utilizamos ese selector para buscar dentro un
// elemento CLASS="elemntoInterior"
Indicamos el nombre del elemento dentro de paréntesis y entre comillas.
Ejemplo:
document.querySelector('nombre_elemento');
// introduciremos el #nombre_ID, .nombre_CLASS, o nombre_etiqueta del elemento
Ejemplo con código HTML:
<div id="un_ID">soy un ID</div>
<div class=".una_CLASS">Soy una clase!</div>
<p>Soy una etiqueta</p>
document.querySelector('#un_ID');
// => <div id="un_ID">soy un ID</div>
document.querySelector('.una_CLASS');
// => <div class="una_CLASS">Soy una clase!</div>
document.querySelector('p');
// => <p>Soy etiqueta</p>
Igual que querySelector. Para realizar múltiples selecciones estas devén de estar separadas por una coma.
Ejemplo:
let todosLosElementos = document.querySelectorAll('elemento1, elemento2');
Ejemplo con código HTML:
<div class="ave">Soy una golondrina</div>
<div class="ave">Soy un aguila</div>
<div class="reptil">Soy una tortuga</div>
let animales = document.querySelectorAll('.ave, .reptil')
// <div class="ave">Soy una golondrina</div>
// <div class="ave">Soy un aguila</div>
// <div class="reptil">Soy una tortuga</div>
querySelectorAll devuelve una NodeList(algo parecido a un Array).
Si estas trabajando con navegadores modernos, tienes que enviar elementos individuales dentro de la Nodelist con una llamada NodeList.forEach.
Si tienes que trabajar con navegadores viejos, necesitas convertir la NodeList en un Array **antes de realizar un bucle con una llamada a **forEach. Puedes utilizar el método Array.from().
// Navegadores modernos
let animales = document.querySelectorAll('.ave, .reptil')
animales.forEach(el => {/* hacer algo con el elemento */})
// Navegadores viejos
let animales = document.querySelectorAll('.ave, .reptil');
// Es posible que necesite un polyfill para Array.from
// Una alternativa, usar Array.prototype.slice.call(animales);
let Array_animales = Array.from(animales);
Array_animales.forEach(el => {/* hacer algo con el elemento */})
Permiten a JavaScript realizar una acción cada vez que se desencadene un evento. ejemplo:
// seleccionamos el elemento button
let boton = document.querySelector('button');
// esto es un oyente de eventos, se activa cuando detecta
// un 'TipoDeEvento' en el elemento que hemos seleccionado
// button, dentro del selector botón:
boton.addEventListener('tipo de evento', nombreDeLaFuncion);
//funcion que activa el oyente de eventos
function nombreDeLaFuncion() {
// Aqui la funcion a realizar cada vez que el elemento botón
// recibe un tipo de evento, por ejemplo al pulsarse
};
Podemos hacer muchas cosas con el objeto de evento, aquí una lista.
Para añadir un oyente de evento, seleccionar el elemento HTML, y llamar al método addEventListener. ejemplo:
Elemento1.addEventListener('click', funcion1)
function funcion1 () {
console.log('has hecho click en algo!')
}
Con el método addEventListener añadimos a Elemento1 un oyente de método el cual al presionar sobre Elemento1 llama a la funcion1 y imprime un mensaje por pantalla.
Para eliminar un oyente de método llamaremos al método removeEventListener incluyendo los parámetros ‘tipoEvento’ y llamada_funcion:
Elemento1.removeEventListener('tipoEvento', llamada_funcion);
Asegurate de eliminar un oyente de eventos tras completar su tarea. Normalmente suele introducirse un removeEventListener dentro de su llamada addEventListener. ejemplo:
Elemento1.addEventListener('click', llamada);
function llamada () {
// muestra un mensaje por pantalla
console.log('has pulsado algo!');
// eliminar el oyente de evento
Elemento1.removeEventListener('click', llamada);
}
Al borrar el oyente de eventos, en el código solo se activara cuando Elemento1 sea pulsado la primera vez, en adelante ya no se activara. Así que, solo debes borrar un oyente de eventos cuando no vas a volver a utilizarlo.
NOTA: Debes borrar un oyente de evento cuando no tienes mas necesidad de utilizarlo para liberar recursos para otras tareas.
Puede crear todo tipo de interacciones simplemente añadiendo (o eliminando) una clase.
let boton = document.querySelector('button');
let nav = document.querySelector('nav');
boton.addEventListener('click', mostrarNAV);
function mostrarNAV() {
// Comprueba si esa clase existe
if (nav.classList.contains('visible')) {
// Si tiene .abierto elimina esa clase
nav.classList.remove('visible');
} else {
// añade .abierto
nav.classList.add('visible');
}
}
Con este ejemplo podemos hacer visible un menú pulsando un botón, y ocultarlo con solo volver a presionar el botón.
Los atributos son una parte importante de los elementos de HTML. Alguna veces, vas a necesitar extraer información de estos atributos para dar contexto a tu JavaScript. Otras veces, necesitaras usar estos atributos para ayudar a escribir interfaces accesibles. ejemplo:
let boton = document.querySelector('button');
let nav = document.querySelector('nav');
boton.addEventListener('click', toggleNav);
function toggleNav() {
// selector de la nav con CLASS="abierto"
let abierto = nav.classList.contains('abierto');
// Si el selector da verdadero (contiene una nav con CLASS="abierto")
if (abierto) {
// borra esa clase
nav.classList.remove('abierto');
// indica al explorador que el menú esta oculto
nav.setAttribute('aria-hidden', true);
// indica que no se puede mostrar el contenido de botón
boton.setAttribute('aria-expanded', false);
}
// y si el selector abierto da false
else {
// agrega la CLASS="abierto"
nav.classList.add('abierto');
// Elimina el atributo que indica que el menú esta oculto
nav.removeAttribute('aria-hidden');
// Da true para que el explorador pueda mostrar el menú
boton.setAttribute('aria-expanded', true);
}
}
Se añade aria-expanded: true/false a botón para indicar al explorador si el menú esta expandido y aria-hidden: true/false a nav para prevenir que el explorador lea el menú cuando esté oculto.
// Ir al atributo
button.getAttribute('aria-expanded');
// Establecer un atributo
button.setAttribute('aria-expanded', true);
// Eliminar un atributo
button.removeAttribute('aria-expanded');
Hay tres pasos para añadir este texto al DOM. Estos son:
ejemplo:
let ul = document.querySelector('ul');
// crear elemento <li>
let li = document.createElement('li');
// Añadir contenido a <li>
li.innerHTML = 'Hola de nuevo, Mundo!';
// Añadir en el DOM
ul.append(li);
Para eliminar un elemento de DOM, necesitas llamar a parentNode.removeChild. Este método toma un parámetro - el elemento a eliminar.
ejemplo:
ul.removeChild(li);
Hay que indicar específicamente el elemento a eliminar:
let padre = document.querySelector('.padre')
let paraEliminar = document.querySelector('.elemento-para-eliminar')
padre.removeChild(paraEliminar)
// Si no quieres escribir un querySelector separado
paraEliminar.parentNode.removeChild(paraEliminar)
Si deseamos borrar el primer o ultimo hijo, con este ejemplo no nos vale, ja que no hay forma de saber cuál es el primer o úlitmo elemento de la lista con clases o identificadores.
En lugar, podemos utilizar parentNode.children para ir a una NodeList con elementos dentro de ul, después, usar un método de Array para ir a un elemento especifico y borrarlo.
ejemplo:
// selector de un elemento ul
let lista = document.querySelector('ul');
// indicamos borrar el primero, al hacer click
removeFirst.addEventListener('click', function {
// si el numero de elementos con padre es mayor a 0
if (lista.children.length) {
// hacemos un selector con el primer hijo que encontramos
let firstNode = list.children[0];
// borramos este elemento
list.removeChild(firstNode);
}
})
Aquí dejo un ejemplo que te ayudara a comprender-lo:
let prepend = document.querySelector('.prepend')
let append = document.querySelector('.append')
let eliminarPrimero = document.querySelector('.eliminarPrimero')
let eliminarUltimo = document.querySelector('.eliminarUltimo')
let lista = document.querySelector('ul')
function crearLi () {
let li = document.createElement('li')
li.innerHTML = 'Hola de nuevo, mundo!'
return li
}
// añade al principio de la lista
prepend.addEventListener('click', e => list.prepend(createLi()))
// añade al final de la lista
append.addEventListener('click', e => list.append(createLi()))
// eliminar primero
eliminarPrimero.addEventListener('click', e => {
if (list.children.length) {
let firstNode = list.children[0]
list.removeChild(firstNode)
}
})
// eliminar ultimo
eliminarUltimo.addEventListener('click', e => {
if (list.children.length) {
let lastNode = list.children[list.children.length - 1]
console.log(lastNode)
list.removeChild(lastNode)
}
})
Si presionas en el botón prepend o append antes, has comprobado que el texto Hola de nuevo, mundo! se añade en el DOM como otro elemento de lista.
A continuación os dejo 2 ejemplos donde se pone en funcionamiento todo lo mencionado en este articulo:
En este ejemplo tendremos un primer botón, que al pulsarlo nos mostrara una lista con todos los animales y otro botón donde pone descripción. La div que contiene la lista esta en el css como opacity. Al pulsar el botón añadiremos la clase abierta la cual dará opacity:1 y hace visible la lista.
Al pulsar el botón descripción que se muestra después de hacer la lista de los animales visible, un selector con todos los li de la lista y los enviara por forEach, añadiendo una clase que los hace opacity:1 y color:red. Aquí os dejo el ejemplo:
HTML:
<button>Mostrar animales</button>
<div>
<ul>
<li>Golondrina <span>Ave</span></li>
<li>Aguila <span>Ave</span></li>
<li>Tortuga <span>Reptil</span></li>
</ul>
<button id="descripcion">Descripción</button>
</div>
CSS:
button {
font-size: 1.5em;
margin: 1em;
padding: 0.5em 0.75em;
}
div {
opacity: 0;
}
.abierta {
opacity:1;
}
span {
color: white;
}
.des {
color:red;
}
JS:
// selector para el oyente de eventos
let boton_animales = document.querySelector('button')
// selector para añadir una clase y poder visualizar la lista
let animales = document.querySelector('div')
// selector donde cojera todos los animales y le añadirá una descripción
let boton_descripcion = animales.querySelector('#descripcion')
// cuando hacemos click en el botón Mostrar animales llama a la función
boton_animales.addEventListener('click', mostrar_animales)
// esta función se encarga de comprobar si el elemento DIV que esta dentro del // selector animales contiene la clase abierta, si la tiene la eliminia y si
// no la añade y hace visible la lista
function mostrar_animales() {
if (animales.classList.contains('abierta')) {
animales.classList.remove('abierta');
boton_descripcion.classList.remove('abierta')
} else {
animales.classList.add('abierta');
boton_descripcion.classList.add('abierta')
}
}
// oyente de método que dispara la funcion mostrar_descripcion al pulsar el
// botón
boton_descripcion.addEventListener('click', mostrar_descripcion)
// creamos un selector añadir_des que va a contener todas las descripciones de // todos los animales de la lista. enviaremos con forEach
// añadiendo una clase a cada una para hacerla visible
function mostrar_descripcion() {
let añadir_des = animales.querySelectorAll('ul li span')
añadir_des.forEach( function () {
if (añadir_des.classList.contains('des')) {
añadir_des.classList.remove('des');
} else {
añadir_des.classList.add('des');
}
})
}
aquí el ejemplo:
HTML:
<button class="añadir">Añadir nombre</button>
<button class="eliminar">Borrar ultimo nombre</button>
<br><br><br>
<div>
</div>
CSS:
button {
font-size: 1em;
margin-top: 1em;
margin-left: 1em;
padding: 0.5em 0.75em;
+ button {
margin-left: 0.5em;
}
}
JS:
// selectores para los oyentes de evento
let añadir = document.querySelector('.añadir')
let eliminar = document.querySelector('.eliminar')
// selector donde añadiremos los nuevos elementos
let list = document.querySelector('div')
// esta función crea un elemento label
function createLabel () {
let label = document.createElement('label')
label.innerHTML = '<br><br>Nombre '
return label
}
// esta función crea un elemento input
function createInput () {
let input = document.createElement('input')
return input
}
// este oyente de eventos se dispara al
// hacer click en el botón añadir.
// a continuación llama a la función
// createLabel y createInput
añadir.addEventListener('click', e => list.prepend(createLabel(),createInput()))
// este oyente de eventos se dispara
// cuando hacemos click en el botón
// eliminar.
// Crea 2 selectores de cada tipo
// con los primeros 2 elementos de
// la Array y los elimina
eliminar.addEventListener('click', e => {
if (list.children.length) {
let label = list.children[0]
list.removeChild(label)
let input = list.children[0]
list.removeChild(input)
}
})
Con esto acabo este articulo. Con el conocimiento adquirido y este documento ya eres capaz de modificar la estructura DOM a tu antojo.
Si tienes alguna duda no dudes en ponerte en contacto conmigo.
Espero haberte ayudado, HASTA LUEGORR!!!
A tope con @mentoringJS!
Jordi Gomper.