duduromeroa.com

#Javascript, #DOMJs, #webinteractiva, #Interfaces, #duduromeroa, #Guayaquil

Javascript

Programación para web: Javascript API DOM 4


George Póyla, matemático. Resolver problemas de diseño. www.duduromeroa.com

Por Eduardo J. Romero Andrade
| Guayaquil

Contacto duduromeroa@gmail.com
Contenido

appendChild(), mouse events, event listeners, event target, propagación de eventos, bubbling, capture, onchange, onblur





AÑADIR NUEVOS ELEMENTOS AL DOM

appendChild()

El método appendChild() adjunta o anexa un nodo o elemento HTML en la cola –es decir, como útimo elemento- de un elemento HTML padre.

En Javascript

// Crear nuevo elemento <div></div> 
let elementoNuevo = document.createElement("div");

// Adjuntar ese elemento a otro ya creado
document.body.appendChild(elementoNuevo);

Svekis y van Putten [5] dan un ejemplo de la sintaxis para crear de la nada un elemento mediante JS DOM API. En el ejemplo de abajo cada click a un botón creará un nuevo elemento <p></p> que muestra el texto 'Sí quiero humita':

En HTML

<!-- Elemento HTML botón. 
Invoca desde onclick la funcion 'preguntar()' -->
<button onclick="preguntar()">Responder</button>

<div id="contenedor">
<!-- Título -->
<h2>Quieres una humita?</h2>
</div>

En Javascript

function preguntar() {
// Crear nuevo elemento 'p'
const nuevoElem = document.createElement("p");

// Crear nuevo nodo texto
const nodoTxt = document.
createTextNode("Claro que quiero humita");

// unir elemento HTML con nodo con nuevoElem()
nuevoElem.appendChild(nodoTxt);

// Apuntar al elemento ID y anexar conjunto para
document.getElementById("contenedor").
appendChild(nuevoElem);
}

/* Cada click en el botón 'Responder' 
genera el texto 'Claro que quiero humita' */

En otro ejemplo se agregarán números a cada click del botón 'Agregar':

En HTML

 <button onclick="numeritos()"> Agregar </button>

En Javascript

function numeritos(){
// Crea nuevo elemento <p></p>
let nuevoElemento = document.createElement("p");
/* - Inserta elemento numérico a 'nuevoElemento'
- random: -de 0 a 1- * 100 
- floor: bajar ese decimal al entero inmediado bajo 
- Multiplicar por 100 dará solo entre cero a 100 */
nuevoElemento.innerText = Math.floor(Math.random() * 100);

/* Anexar nuevo elemento al elemento 'body' */
document.body.appendChild(nuevoElemento);

/* Cada click al botón 'Agregar' genera un 
número aleatorio entre 0 a 100 */
}

INTERACCIÓN MEDIANTE EVENTOS

Eventos basados en HTML y eventos basados en JS.

El conjunto de eventos HTML están reunidos en el Global Event Attributes. A su vez se dividen en: Window Event Attributes, Form Events, Keyboard Events, Mouse Events, Drag Events, Clipboard Events, Media Events y Misc Events.

Un ejemplo de eventos con HTML. Con este método solo se puede agregar SOLO un evento por elemento HTML y es imposible cambiar el evento directamente:

En HTML

<!-- El elemento HTML 'p' ejecuta la función 
'ejecutar()' mediante un click a ese elemento -->
<p id="unico" onclick="ejecutar()">Click</p>

Un ejemplo de eventos con JS. Allí se está asignando directamente una función interna lista para ser ejecutada.

En Javascript

/* - Apunta a un elemento con id 'unico'
- Accede al evento onclick para activar 
una función DENTRO de otra función */
document.getElementById("unico").onclick = 
// Función anónima
function(){
// Función interna, activable
magic();
}; // Ojo punto y coma 

ESPECIFICANDO EVENTOS CON EVENT LISTENERS

addEventListener()

addEventListener() permite agregar múltiples funciones para un solo evento -como click, load, focus, blur, change, etc–. Ojo con la función ejecutar -va sin ( )-. Por cada evento se necesita un addEventListener().

En Javascript

/* Apunta a un elemento con el ID 'cosa' */
document.getElementById("cosa").
/* Agrega un evento click que activará la función 'ejecutar' */
// 
addEventListener("click", ejecutar);

Si se desea agregar parámetros en una función, se debe usar una función anónima:

En Javascript

/* Apunta a elemento ID 'unico' */
document.getElementById("unico").
/* Agrega evento 'click' que 
ejecutará función magic...*/
addEventListener("click", function(){
// ...que a su ves contiene dos argumentos.
magic(arg1, arg2)
});

// OJO CON CIERRE DE EXPRESIONES
document.getElementById("...").
addEventListener("...", function(){
function( )
} // Cierra funcion
); // Cierra addEventLis....

onload()

Ejecutará desde la función todo elemento contenido en el DOM y que haya finalizado de cargar carga en el sitio web.

DOMContentLoaded()

Ejecutará cualquier función después de que el DOM haya sido construído.

En Javascript

document.addEventListener("DOMContentLoaded", 
(e) => { console.log(e) }
);

MOUSE EVENT HANDLERS

Eventos activados desde cada intervención del mouse:

  • ondblclick: clickear dos veces
  • onmousedown: clickear pero no soltar
  • onmouseup: clickear y soltar
  • onmouseenter: Activa evento al desplazar el puntero sobre un elemento y mantenerlo así.
  • onmouseleave: Activa evento al desplazar el puntero sobre un elemento y luego sacarlo del área.
  • onmousemove:Activa evento al desplazar el puntero sobre un elemento.
  • onmouseout: Activa un evento solo cuando el puntero ha dejado el elemento.
  • onmouseover: activa algo mientras se desplaza el puntero sobre un elemento.

El siguiente ejemplo activa un evento –cambiar de color– cuando se posa el puntero sobre un cuadrado:

En HTML

<!-- Un div con id 'recuadro' activa desde 
un evento de mouse la función cambiarColor() -->
 <div id="recuadro" onmouseover="cambiarColor()" 
style="width:100px;height:100px;background-color:pink;"></div>

En Javascript

/* Función cambiarColor() apunta a un 
elemento con el ID 'recuadro' cuya regla 
de estilo gráfico es background-color = "blue";*/
function cambiarColor(){
document.getElementById("recuadro").
style.backgroundColor = "blue";
}

En otro ejemplo se usarán addEventListeners() cuya función interna es vinculada mediante 'this' y cuyos valores de parámetros se vinculan con la función cambiarColor():

En el ejemplo de abajo: un click sobre el recuadro gris lo volverá verde; y superponer el cursor sobre el recuadro lo volverá rojo. Es decir, de esta forma más de un evento está ocurriendo desde la interacción del cursor sobre el recuadro.

Ojo cómo se usó la clave this como primer argumento de la función cambiarColor():

En HTML

<!-- Elemento id 'recuadro' con reglas CSS insertas -->
<div id="recuadro" 
style="width:100px;
height:100px;
background-color:grey;">

En Javascript

/* onload carga funcion hacerlYa() 
cuando el sitio se cargue  */
window.onload = function hacerlYa(){

/* Apunta a elemento id 'recuadro' */
document.getElementById("recuadro").
/* Carga evento mousedown SIN 'on'...  */
/* Función anónima carga función 
interna cambiarColor()  */
addEventListener("mousedown", function() {
/* cambiarColor() con dos argumentos */
cambiarColor(this, "green");
});

// Igual acá
document.getElementById("recuadro").
addEventListener("mouseover", function() {
cambiarColor(this, "red");
});

} // cierra onload
 
/* LA FUNCIÓN */
// Dos parámetros: cosita, color
function cambiarColor(cosita, color){
/* cosita corresponde a la regla backgroundColor */
/* color corresponde al argumento que sea 
ingresado desde los Listeners... */
cosita.style.backgroundColor = color;
}

PROPIEDAD EVENT.TARGET()

Cuando un evento se activa una de sus variables están 'visibles junto con sus propiedades'.

Por otro lado, la propiedad target es un elemento HTML que 'dispara' el evento. Y es útil para obtener info desde la página web como subeventos y elementos con relación. Muy útil para evaluar comportamientos de formularios. Svekis y van Putten[5] dan un ejemplo:

En HTML

<button type="button" onclick="hacer()">Click</button>

En Javascript

function hacer(){
// Obtiene datos cuando el evento es ejecutado
console.dir(event.target);

/* EN CONSOLA */
/* > button
accessKey:""
ariaAtomic: null
ariaAutoComplete: null
.... */
}

En este ejemplo más complejo se usa event.target para vincular funciones con argumentos propios:

En HTML

<!-- Se arma formulario -->
<div id="saludo"> Ingrese datos </div>
<form>
<input type="text" name="name" placeholder="nom" />
<input type="text" name="apellido" placeholder="ape" />

<!-- Evento onclick() activa función sendInfo()-->
<input type="button" onclick="sendInfo()" value="Submit" />
</form>

En Javascript

function sendInfo(){
/* Añade padre al evento */
/* El elemento padre del botón es el elemento <form>. 
Se alojará en variable 'p' */
let p = event.target.parentElement;

/* p.name.value y p.apellido.value obtienen mediante 'values' 
el valor de cada campo de formulario */
mensajito("HOLA " + p.name.value + " " + p.apellido.value);
} // Cierra sendInfo()  

// Función externa
function mensajito(argumento){
/* - Apunta al elemento ID 'saludo' 
- Inserta mediante innerHTML todo lo que se 
ingrese desde los campos del formulario - */
document.getElementById("saludo").innerHTML = argumento;
}

Gracias a que event.target obtiene los valores de los nombres insertados en los campos name="name" y name="apellido" es que se pueden lanzar un mensaje cuando el evento ha sido ejecutado desde el <input type="button" ...>

FLUJO O PROPAGACIÓN DE EVENTOS DOM –EVENT BUBBLING y EVENT CAPTURING

La fase de bubbling -en español, borboteo– refiere a un despliegue de acciones entre elementos padre anidados. Según la fase bubbling, cada ejecución de evento 'moja' de dentro hacia afuera cada elemento padre presente en el flujo de relaciones de elementos anidados.

En HTML

// ESTRUCTURA DE ELEMENTOS
a) Elemento padre
      | b) hijo. Elemento padre
                  | c) hijo. Elemento padre
                            | d) hijo 

// ACTIVAR EVENTO DESDE ELEMENTO d)
- Evento se propaga desde el activador hacia afuera
       d --> c --> b --> a

// ACTIVAR EVENTO DESDE ELEMENTO b)
- Evento se propaga desde el activador hacia afuera
       b --> a

En otras palabras, el evento se propaga desde el elemento que lo activó hasta el último elemento padre faltante.

¿Qué sucede si deseamos anular esa propagación de elementos padre anidados cuando ejecutamos un evento?:

  • Si la sintaxis de addEventListener() es:
  • addEventListener(evento, listener, useCapture)
  • Donde useCapture corresponde a fases booleanas de ejecución
  • Entonces desactivamos bubbling mediante:
  • addEventListener(tipo, listener, true)

En Javascript

elementoId.
addEventListener("tipoEvento", funcionAllamar, true);

/* El tercer argumento booleano del addEventListener() 
cancela con true la propagación del evento ejecutado. 
Recordar que el valor por default es false */

¿Qué ocasiona ese cambio en la propagación del evento? Con el valor de true en el tercer argumento del addEvent... se crea un tipo de evento llamado event capturing; es es, que el despliegue del evento inicie desde afuera hacia dentro. Sin embargo, este es un método muy poco usado y no siempre requerido.

DELEGACIÓN DE EVENTOS -EVENT DELEGATION-

Este principio busca simplificar el trabajo de agregar controladores de eventos a cada elemento presente -sean 5, 500 elementos o más-. El concepto de event delegation propone agregar un solo controlador a un solo elemento padre de elementos hijos y así, cada evento se propagará desde el elemento activador del evento hacia su padre -en fase bubbling-; o desde el padre hacia sus hijos –fase capture, muy poco usada-.

Eventos onchange, onblur

Eventos comunes en campos de ingreso de datos –también llamados formularios-.

onblur() se activa cuando un campo de ingreso de datos es soltado por el puntero del mouse luego de haber ingresado un dato –como texto o número–.

onchange() se activa cuando el valor de campo de ingreso de datos ha cambiado. Es muy común usarlo en formularios y selección de menus.

En otras palabras, sea la acción o evento que hayamos creado estas se activarán cuando alejemos el puntero luego de haber ingresado un dato –onblur()– o cuando el valor de un dato haya cambiado –onchange()–.

En HTML

<div id="Bienvenido">Bienvenido, </div>
<form> 

<!-- evento onchange() cuando se active insertar() -->
<input type="text" name="nombre" placeholder="..." onchange="insertar()" />
<input type="text" name="apellido" placeholder="..." onchange="insertar()" />

<!-- evento onclick() cuando se active enviarInfo() -->
<input type="button" onclick="enviarInfo()" value="Submit" />
</form>

En Javascript

function insertar(){
// Retorna el ELEMENTO que activó el evento
let p = event.target;
/* Si identificador del nombre del evento es 'nombre' */
if (p.name == "nombre")
// Activar función enviarMensaje(m)
// p.value toma el valor del campo de la variable 'p'
{ enviarMensaje("holi" + p.value);} 
else { enviarMensaje("holi" + p.value)}
}

function enviarInfo(){
// Obtiene el PADRE del elemento disparador de evento
let p = event.target.parentElement;
// Se activa función 
enviarMensaje("Hola, " + p.nombre.value + " " + p.apellido.value)
}

function enviarMensaje(m){
// Apunta al elemento con el id 'Bienvenido'
// inserta lo que se ingrese como argumento más arriba
document.getElementById("Bienvenido").innerHTML = m;
}

CONTROLADOR DE EVENTOS CLAVE

Key event handler

onkeypress. activa un evento cuando una tecla es presionada y soltada luego.

onkeydown. activa un evento solo cuando una tecla es presionada.

onkeyup. activa un evento solo cuando una tecla es soltada.


BIBLIOGRAFÍA:
    3ra edición. 2018. Marijn Haverbeke. No starch press.
    [2] MDN Web Docs, Javascript. Mozilla Foundation.
    David Flanagan (2020). Editorial O'Reilly.
    Ved Antani, Stoyan Stefanov (2017). Packt Publishing.
    Editorial Packt.
    Information and Computation. Elsevier.
    ACM SIGCSE BulletinVolume 19Issue