duduromeroa.com

#Javascript, #APImouseEvents, #webinteractiva, #interfaces, #duduromeroa, #Guayaquil

Javascript | DOM | API

Programación para web: estudio de eventos clic con mouseEvents DOM object en Javascript


JS, eventos, escuchas de eventos, DOM. www.duduromeroa.com

Por Eduardo J. Romero Andrade
| Guayaquil

Contacto duduromeroa@gmail.com

#Javascript, #APImouseEvents

Aclaraciones
Contenido para quienes ya comprenden y practican HTML, CSS y JS. Adjunto bibliografía al final de esta página.


En algunos ejemplos de código añadí espacios entre los caracteres para resaltar la sintaxis. La original NO usa esos espacios.


En casi todos los ejercicios expongo código y comentarios. Puedes revisarlo en: (click derecho en esta página desde mouse > Inspect Element > sources ).



Objeto DOM mouseEvents

En otra sección ya se detalló . En resumen, se usan los objetos para concentrar mediante código muchas propiedades con sus valores, en forma de datos únicos o categorizados en , que a su vez podrían comunicarse o no (según lo determinemos) con otros objetos y sus datos.

Por lo tanto, los eventos del objeto mouseEvents contienen datos que permiten comunicar, detectar otros datos de entrada, alterar y ejecutar eventos sobre los elementos contenidos todos ellos en toda la ventana de un navegador web. Los datos de entrada serán creados desde un medio externo, como son los movimientos y clics desde un mouse de computadora.

Recalco eso último, los eventos del objeto mouseEvent son exclusivos para interacciones con puntero de ratón. Sin embargo, muchos navegadores web asimilan ambos objetos de interacción (como el clic de mouse o el dedo sobre la pantalla táctil) desde uno o más eventos del objeto mouseEvent. En otras palabras, se acepta que algunos eventos mouseEvent sea activado al cliquear o al tocar un elemento en pantalla táctil. Y esa decisión de aceptar o no dependerá de las normativas técnicas de cada navegador.

Otras tecnologías, intentan unificar las interacciones (de clics y táctiles) desde un solo código. Pero ese es otro gran tema que se revisará más adelante.

Primero se revisarán los 10 eventos contenidos en el objeto mouseEvents. Se aclara que el prefijo 'on' en cada nombre de evento es un legado de anteriores estándares de identificación. Pero ese prefijo se elimina cuando se use un manejador de eventos como eventListener:

  • onclick evento se activa al cliquear y soltar un elemento en pantalla
  • oncontextmenu evento se activa al presionar clic derecho
  • ondblclick evento se activa al cliquear dos veces
  • onmousedown evento solo se activa al cliquear desde cualquier botón del mouse sobre un elemento
  • onmouseenter evento se activa al deslizar el puntero del mouse hacia y sobre un elemento. Luego del evento, la acción activada se mantiene si el puntero sale del evento.
  • onmouseleave evento se activa al deslizar el puntero sobre un elemento y luego alejarse. Si no se aleja no se desactiva.
  • onmousemove evento se activa al deslizar el puntero encima de un elemento. Y el evento no se desactiva si el puntero se aleja del elemento.
  • onmouseout evento se activa al deslizar el puntero encima de un elemento y luego alejarse de él
  • onmouseover evento se activa al deslizar el puntero sobre un elemento
  • onmouseup evento se activa al cliquear y soltar el clic sobre un elemento

Luego, se revisarán las 16 propiedades contenidas en el objeto mouseEvents.

  • altKey representa la presión de la tecla ALT
  • button representa la presión de un botón del mouse
  • buttons representa la presión de todos los botones del mouse
  • clientX representa los datos de las coordenadas en dirección horizontal de ubicación (según la ventana del navegador) del mouse
  • clientY representa representa los datos de las coordenadas en dirección vertical de ubicación (según la ventana del navegador) del mouse
  • ctrlKey representa la presión de la tecla Control
  • detail representa datos del evento
  • metaKey representa la presión de la tecla Meta
  • offsetX representa los datos de las coordenadas en dirección horizontal de ubicación (según el elemento apuntado) del mouse
  • offsetY representa los datos de las coordenadas en dirección vertical de ubicación (según el elemento apuntado) del mouse
  • pageX representa los datos de las coordenadas en dirección horizontal de ubicación del mouse (según el documento)
  • pageY representa los datos de las coordenadas en dirección vertical de ubicación del mouse (según el documento)
  • relatedTarget representa
  • screenX representa los datos de las coordenadas en dirección horizontal de ubicación (según una caja de ventana)
  • screenY representa los datos de las coordenadas en dirección vertical de ubicación del mouse (según una caja de ventana)
  • shiftKey representa la presión de la tecla Shift

MouseEvents y preventDefault();


El método preventDefault(); no es un método aplicable para eventos de puntero de ratón, pero sí para eventos táctiles.


El método preventDefault(); bloquea un comportamiento natural de una funcion, siempre que ese comportamiento sea bloqueable.


Por ejemplo, si deseamos que un eventListener nos permita tocar y arrastrar un elemento en pantalla táctil, será necesario ordenar al navegador que cancele su comportamiento táctil natural o de scroll. Y esa orden se la da añadiendo un 'preventDefault()' dentro del eventListener:


En Javascript

/* Se vincula un elemento interactivo con un evento táctil */
elemento.addEventListener('touchstart', 
function(accionInteractiva) {
// Cancela comportamiento de scroll 
accionInteractiva.preventDefault(); 

/* codigo a ejecutar */
});

Es lógico que un evento táctil (tocar o deslizar un elemento visual con la punta del dedo sobre la pantalla) requiera bloquear un comportamiento de scroll en pantalla. Sino, sería incómodo si este evento se contrapone con la acción de scroll. Sin embargo, eso no se necesita con un evento de puntero de mouse. El puntero apenas es otro elemento digital que toca un elemento digital. Es por eso que aplicar preventDefault(); en eventos de puntero de ratón, como mouseEvent no ofrece resultado cuando se combina eventos mouseEvent con interacción táctil. Es por eso que se aconseja en muchos casos usar eventos según el tipo de interacción.


El código inferior representa un evento exclusivo para puntero de mouse. Puesto que el contacto de ese tipo de puntero no requiere bloqueal el comportamiento de scroll del navegador, la función preventDefault(); no tendrá efecto alguno. Peor aún, si se desea aplicar ese tipo de evento con una interacción táctil.


En Javascript

boton.addEventListener('mouseout', function(event){
event.preventDefault(); 
/* code */
}); 


Evento click

Evento ejecuta código cuando se cliquea y se suelta el botón o cualquiera de los botones del mouse. Puede ser invocado accediendo al evento o desde un eventListener.

Es más, todos los eventos DOM pueden ser accedidos de estas dos formas, con importantes diferencias de concepto. Atención: los eventListeners solo admiten los nombres de los eventos sin el prefijo 'on'.

En Javascript

/* Modelo A: Vinculando un elemento directamente al evento, 
y que eso sea igual a una función */
elementoHTML.onclick = function(){ /*...*/ }; 

// - - - - - - - - -

/* Modelo B: Vinculando un elemento a un addEventListener */
/* OJO AQUÍ: el evento solo esta mostrado sin el prefijo 'on' */
elementoHTML.addEventListener("click", function);
function() {
/*...*/
}

// - - - - - - - - -

/* Vinculando un addEventListener a una función 
con parámetro de evento  */
elementoHTML.addEventListener("mouseover", function(event) {
/*...*/
});

En algunos navegadores admite mediante toque táctil. Ejecuta el evento al tocar y soltar el toque.

Toca aquí

Hay que tener en cuenta cuáles propiedades JS serán las que alteran los elementos del DOM, y cuáles solo agregan propiedades y valores; sin que eso signifique que están alterando el elemento.

En el siguiente ejemplo solo una línea de código JS (elem. style. fill = "orange";) es la que altera el color del círculo mediante un click. Mientras que otra línea solo asignará la propiedad color; pero no la activará por ahora:

En Javascript

circulo1.addEventListener("click", function () {
if (isYellow) {
// Sí afecta el color porq actualiza la regla CSS
circulo1.style.fill = "green";

isYellow = false;
} else {
// NO afecta el color porque solo añade un atributo de color
circulo1.setAttribute("fill", "red");

// Sí afecta el color porq actualiza la regla CSS
circulo1.style.fill = "orange";

isYellow = true;
}
});

Evento contextmenu

Abajo. Se activa cuando se cliquea sobre el elemento interactivo pero desde el botón derecho del mouse. Lo que se ejecute luego de eso se definirá en el cuerpo del eventListener. Es importante bloquear mediante event.preventDefault(); el comportamiento estándart del click derecho, en donde se muestra un menú ya definido desde todo navegador.

En otras palabras, cuando ya se haya definido el evento oncontextmenu, el clic sobre el elemento no ejecutará nada; solo se ejecutará el código del eventListener cuando se haga clic con el botón derecho del mouse.

Por obviedad, este evento es exclusivo para puntero de mouse.

Cliquea con botón derecho de mouse

Evento dblclick

Abajo. El evento se activa cuando se cliquea (en seguidilla) dos veces sobre el elemento interactivo. En algunos navegadores aplica para toque táctil.

Cliquea dos veces

Evento mousedown

Abajo. El evento se activa cuando se cliquea (soltando o no el clic) sobre el elemento interactivo. Apenas cliquear (sin soltar) el evento ejecuta el eventListener. En algunos navegadores aplica para toque táctil.

Cliquea

Evento mouseenter

Evento se activa solo cuando el puntero del mouse ingresa al área del elemento interactivo. Ojo: el evento se mantendrá activado aún si el puntero del mouse sale del elemento. No es un evento propagable desde elementos hijos a padres. Por lo que se activará de igual manera si el puntero del mouse entra al elemento padre o a los elementos hijos más internos.

No es un evento congruente con toque táctil.

Desliza el puntero encima del gris

Evento mouseleave

Evento se activa solo cuando el puntero del mouse ingresa y se desliza hacia afuera del área del elemento interactivo. No propaga esa activación desde subelementos hacia el elemento interactivo.

No es un evento congruente con toque táctil.

Con el puntero del mouse, entra y sale del área gris

Evento mousemove

Evento se activa cuando el puntero entra y se mueve dentro del área del elemento interactivo, enviando datos de los pixeles de ubicación; y se desactiva cuando el puntero sale del área.

Permite toque táctil pero es irregular y solo lee datos en cada toque.

Con el puntero del mouse, entra y sale del área gris

Evento mouseout

Evento se activa cuando el puntero del mouse entra y sale del elemento padre o de uno de sus hijos. Hay que prestar atención en esto: el evento mouseout permite activarse incluso desde subelementos internos al elemento interactivo principal; es decir, permite ejecutar el evento desde afuera hacia dentro, y viceversa.

Ese modo de ejecución de un evento se conoce como propagación o bublling, anglicismo que refiere al burbujeo desde dentro hacia afuera del evento. Ni mouseenter ni mouseleave permiten propagación. Es decir, aunque existan subelementos internos al elemento padre, al aplicar ese evento todos los subelementos serán interpretados como un solo elemento.

En otras palabras, en el ejemplo de abajo el evento mouseout se activará de igual manera si el puntero del mouse entra y sale desde el área del padre, o desde el área del hijo1, o desde el área del hijo2.

Finalmente, mouseout no es un evento congruente con toque táctil.

padre
hijo1
hijo2

Evento onmouseover

Se activa cuando el puntero del mouse entra o se posa sobre el elemento interactivo o en uno de sus subelementos o hijos. Pero no se activa cuando el puntero sale del elemento. En cambio, onmouseover se activa cuando el puntero sale del área del elemento interactivo.


Este no es un evento activable mediante clic, pero sí para deslizar y meter el puntero sobre el área interactiva. Por lo tanto es incongruente con una acción táctil.


Padre
Hijo1
Hijo1

Evento onmouseup

Se activa cuando un clic de mouse es presionado y luego soltado sobre un elemento interactivo. Es decir, un clic no activará el evento, pero sí un clic + soltar.

onmouseup es compatible con toque táctil al soltar luego de tocar sobre la pantalla.

Ojo como se ha aplicado las siguientes reglas CSS desde el eventListener, especialmente en 'transform':

En CSS

// Cambia posición, escala y rotación
elemento.style.transform = "scale(0.4) translateY(2em) rotate(90deg)";
// Agrega tiempo de animación
elemento.style.transition = "1s ease-in";

Padre
Hijo1

Hasta aquí los 10 eventos contenidos en el objeto mouseEvents.

Por otro lado, las 16 propiedades del objeto MouseEvent obtienen datos numéricos tomados de los eventos hechos con el mouse; por ejemplo, para verificar que se ha presionado uno de los botones del mouse, se usará la propiedad button. Esta envía enteros del 0 al 4 para determinar qué botón fue presionado.

RECORDAR
En algunos contextos como la función console.log(); todo lo que esté entre comillas NUNCA será ejecutable, simplemente será mostrado como un mensaje de texto. Lo de abajo es un ERROR si lo que se busca es ejecutar la propiedad button desde un parámetro de función del eventListener...


En Javascript

console.log("minion.button");
/* Esto simplemente mostrará 'minion.button' en consola */


Las propiedades se invocan desde el parámetro de la función. Por convención es nombrado como 'event', pero no es obligatorio. Yo le puse 'minion'. El código correcto es el siguiente:

En Javascript

// Se toma el elemento HTML
var apuntaElemento = document.querySelector(".elemento"); 

/* Se accede a evento mousedown */
apuntaElemento.addEventListener('mousedown', function(minion){

/* Y el parámetro 'minion' se usará para 
acceder a la propiedad 'button' */
console.log(minion.button);
}); 

Propiedad button

La propiedad button se ejecuta siendo accedida primero por el parámetro de la función del eventListener (ver ejemplo arriba). El valor de la propiedad button indica qué botón del mouse ha sido presionado.

  • 0 :: Corresponde al botón principal
  • 1 :: Corresponde al botón central o giratorio
  • 2 :: Corresponde al botón derecho
  • 3 :: Corresponde al botón cuarto (en caso de haber)
  • 4 :: Corresponde al botón quinto (en caso de haber)

Una acción táctil también podría activar la propiedad button. ¿Por qué?. Puesto que el eventListener se activa inicialmente con un evento mousedown, este evento sí interpreta un toque táctil como si fuera un evento clic de mouse.

Clic aquí

Quedan pendientes el resto de las propiedades del objeto mouseEvent.


BIBLIOGRAFÍA:
[1] Eloquent JavaScript 3ra edición. 2018. Marijn Haverbeke. No starch press.
[2] MDN Web Docs, Javascript. Mozilla Foundation.
[3] JavaScript: The Definitive Guide. David Flanagan (2020). Editorial O'Reilly.
[4] Object-Oriented JavaScript Ved Antani, Stoyan Stefanov (2017). Packt Publishing.
[5] Laurence Lars Svekis, Maaike van Putten. JavaScript from Beginner to Professional: Learn JavaScript quickly by building fun, interactive, and dynamic web apps, games, and pages (2021). Editorial Packt.
[6] Black, A. P. (2013) Object-oriented programming: Some history, and challenges for the next fifty years. Information and Computation. Elsevier.
[7] John R. Pugh, Wilf R. LaLonde, David A. Thomas (1987) Introducing object-oriented programming into the computer science curriculum. ACM SIGCSE BulletinVolume 19Issue 1Feb
[8] W3C. JavaScript HTML DOM Navigation