Eventos (teclado), agregar/eliminar elementos de DOM y loops
Resumen
Hoy terminamos de ver DOM (por lo menos como tema principal) y vemos loops. Este día fue más divertido porque me rompí un poco la cabeza pensando un ToDo list.
El tema estrella va a ser la arrow function, que utilizaremos bastante a partir de ahora.
Podrás ver la lista de los 100 días en este enlace.
Eventos (teclado)
Son eventos que ocurren cuando el usuario apreta alguna tecla. Con onchange
detecta cambios que se realizen en un input y acciona solo si dejamos el campo (o interactuamos con otro elemento) y si hay cambios con el valor anterior.
En el caso de un input, si agregamos un texto en el campo y luego hacemos click fuera de este, acciona onchange
.
<input type="text" onchange="handleChange()" />
function handleChange(){
console.log("Sacá la mano de ahí!");
}
Esto nos sirve para poder validar formularios. Esto lo podemos hacer así:
<input id="nombre" type="text" onchange="nameInput()" />
<span id="nameError"></span>
function nameInput(){
const input = document.getElementById('nombre');
const value = input.value;
const error = document.getElementById('nameError');
if (value.length == 0){
error.innerHTML = "Campo vacio!";
console.log('Campo vacio!');
} else{
error.innerHTML = "";
}
}
Otro evento es onkeypress
. Acciona cuando apretamos una tecla cualquiera. Si seguimos utilizando el input como ejemplo:
<input id="nombre" type="text" onkeypress="nameInput()" />
function nameInput(){
const input = document.getElementyById('nombre');
console.log(input.value);
}
El problema con este ejemplo es que el input actualiza el input.value
solamente cuando realizar otra acción. O sea, si escribimos "Javier", desde consola vemos algo así:
J
Ja
Jav
Javi
Javie
Una solución para esto es:
<input id="nombre" type="text" onkeyup="nameInput(event)" />
function nameInput(e){
console.log(e.target.value);
}
En lugar de utilizar onkeypress
, usamos onkeyup
para detectar todas las teclas presionadas, obteniendo el valor final del input. También mandamos como argumento event
a la función nameInput
para no tener que buscar el elemento HTML (mejoramos la performance del código).
Ahora, viendo algo más elaborado, mostramos en un elemento label
a través de un botón el valor actual de un input:
<input id="msgInput" type="text" />
<button onclick="msgShow()">Mostrar mensaje</button><br />
<label id="msgLabel"></label>
function msgShow(){
const input = document.getElementById('msgInput');
const label = document.getElementById('msgLabel');
label.innerHTML = input.value;
}
En el botón usamos el evento onclick
para que ejecute la función msgShow
solo si hacemos click en él.
Si no queremos utilizar un botón y si queremos que todo lo que escriba en input se vea reflejado en el label, ahí debería utilizar el evento onpress
.
Agregar y eliminar elementos del DOM
Tal cual como lees, podemos agregar y eliminar elementos HTML, con solo JS. Una forma de ver esto es haciendo una pequeña app "ToDo List".
Para crear un ToDo list, necesitamos tener si o si un elemento HTML que hará de rol de "padre" para poder replicarla y tener elementos HTML "hijos".
Primero, veamos algo "sencillo":
<body>
<ul id="list">
</ul>
</body>
function addItem(value){
const list = document.getElementById('list');
const item = document.createElement('li'); // Creamos un elemento li
const text = document.createTextNode(value); // Creamos un nodo de texto
item.appendChild(text); // Metemos el nodo de texto dentro de li
list.appendChild(item); // Metemos li dentro de ul (list)
}
Con esto solo, tenemos una lista y agregamos nuevos elementos li desde consola. Esto mismo se puede realizar con el método innerHTML
que es más sencillo y fácil de leer, pero tiene problemas de seguridad! (XSS).
La idea principal de este script, en resumen, es:
- Crear un nodo de texto
- Crear un elemento
- Obtener información de la lista
- Meter el nodo de texto dentro del elemento creado y luego meterlo en la lista
Ahora crearemos el ToDo list, agregando un input, un botón y la función para eliminar elementos. Jugaremos con algunos métodos y eventos nuevos:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ToDo List</title>
</head>
<body>
<input id="inputTask" type="text" onkeydown="addTaskKey(event)" />
<button onclick="addTask()">Agregar</button>
<ul id="list">
</ul>
<!-- Un poco de estilo por acá -->
<style>
li, label{
margin: 10px ;
}
li{
list-style:none;
}
label{
background-color: red;
color: white;
padding: 1px 5px;
border-radius: 25%;
cursor: pointer;
font-family: Arial, Helvetica, sans-serif;
}
</style>
<!-- Un poquitín de código por acá -->
<script>
let idTask = 0;
// Función para input con evento
function addTaskKey(e) {
if (e.key == "Enter" || e.key == "+"){
addTask();
}
}
// Función para agregar tarea en lista
function addTask(){
const taskValue = document.getElementById('inputTask').value;
if (taskValue != ""){
createElement('label', 'X', 'list')
createElement('li', taskValue, 'list'); // Entro a otra función
idTask += 1;
document.getElementById('inputTask').value = '';
}
}
// Función para eliminar tarea en lista por id
function deleteTask(idE){
const task = document.getElementById('task_' + idE);
const father = document.getElementById('list');
father.removeChild(task);
}
// Función para crear elementos HTML
function createElement(type, content, parentId){
const parent = document.getElementById(parentId)
const elem = document.createElement(type);
const text = document.createTextNode(content);
elem.appendChild(text);
parent.appendChild(elem);
// Agrego atributos a label o li
if (type == 'label'){
elem.setAttribute('id', 'taskDel_' + idTask);
elem.setAttribute('onClick', `deleteTask(${idTask})`);
} else {
elem.setAttribute('id', 'task_' + idTask);
const elemLabel = document.getElementById('taskDel_' + idTask);
elem.appendChild(elemLabel);
}
}
</script>
</body>
</html>
removeChild
, como se imaginarán, lo uso para eliminar el elemento hijo del padre (en este caso, el li dentro del ul).
setAttribute
es un método bastante útil para ingresar atributos nuevos a un elemento HTML (que no existían en este ejercicio).
Loops
Por fin, vemos los bucles. No los hemos visto antes para que nos rompamos un poco el coco y demostrar que no necesitamos de los bucles. Hay un límite para decir esto :P.
Hay varios tipos de loops: for
, while
, map
. for
y while
no se consideran funcionales, map
si. La diferencia principal es que map es exclusivo para iterar arrays.
// for (inicio; fin; incremento)
let randomNumbers = [];
for (let i = 0; i < 10; i++){
const random = Math.random();
randomNumbers.push(random); // Array de 10 numeros randoms
}
console.log(randomNumbers);
No es muy difícil de entender la lógica. El bucle for
se puede usar para todo lo que necesite iterar.
// Imprime por consola el valor de i mientras sea menor o igual que 9.9
let i = 0;
while (i <= 9.9){
i = Math.random() * 10;
console.log(i);
}
El bucle while
tampoco es difícil de entender. Itera siempre hasta que no cumpla con una condición. Al ejemplo de arriba no les recomiendo que pongan while(i <= 9.9999)
, es casi imposible de que rompa la condición y se les va a colgar el navegador.
const personas = ['Bombon', 'Burbuja', 'Bellota'];
personas.map((persona) => {
console.log(persona);
});
Como mencionamos antes, map
solo sirve para iterar arrays. Lo importante es que estamos implementando las "arrow functions" o funciones flecha. Es algo que implementaron en ES6. Es una función que no tiene nombre.
En el ejemplo, como argumento de la función flecha le pasamos persona
, que va a ser el valor de cada iteración.
Otro ejemplo sería:
const numbers = [3, 1, 9];
const doble = numbers.map((num) => {
return num * 2;
});
console.log(doble);
Algo copado de acá es que podemos guardar el resultado de map
dentro de una variable. También usamos el return
para que podamos obtener el doble del valor actual en el array y guardarlo en otro array.
Día 5/100
Top comments (0)