DEV Community

Cover image for #CienDiasConCourseIt: Día 5/100
Javier Rodriguez
Javier Rodriguez

Posted on • Updated on

#CienDiasConCourseIt: Día 5/100

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()" />
Enter fullscreen mode Exit fullscreen mode
function handleChange(){
    console.log("Sacá la mano de ahí!");
}
Enter fullscreen mode Exit fullscreen mode

Esto nos sirve para poder validar formularios. Esto lo podemos hacer así:

<input id="nombre" type="text" onchange="nameInput()" />
<span id="nameError"></span>
Enter fullscreen mode Exit fullscreen mode
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 = "";
    }
}
Enter fullscreen mode Exit fullscreen mode

Otro evento es onkeypress. Acciona cuando apretamos una tecla cualquiera. Si seguimos utilizando el input como ejemplo:

<input id="nombre" type="text" onkeypress="nameInput()" />
Enter fullscreen mode Exit fullscreen mode
function nameInput(){
    const input = document.getElementyById('nombre');

    console.log(input.value);
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Una solución para esto es:

<input id="nombre" type="text" onkeyup="nameInput(event)" />
Enter fullscreen mode Exit fullscreen mode
function nameInput(e){
    console.log(e.target.value);
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode
function msgShow(){
    const input = document.getElementById('msgInput');
    const label = document.getElementById('msgLabel');

    label.innerHTML = input.value;
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode
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)
}
Enter fullscreen mode Exit fullscreen mode

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:

  1. Crear un nodo de texto
  2. Crear un elemento
  3. Obtener información de la lista
  4. 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>
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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);
}
Enter fullscreen mode Exit fullscreen mode

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);
});
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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)