Eventos personalizados y la API de eventos especiales en jQuery

Las páginas web, en su mayor parte, son impulsadas por eventos. Las bibliotecas como jQuery han proporcionado métodos de ayuda para que esta funcionalidad sea mucho más fácil de comprender. En este tutorial, veremos cómo expandir estos métodos para crear sus propios eventos de espacio de nombre personalizados.


Eventos en JavaScript

Antes del lujo de las bibliotecas de JavaScript, si desea agregar un evento de clic simple a un elemento que necesita para hacer el seguimiento para todos los navegadores:

 var elt = document.getElementById ("# myBtn"); if (elt.addEventListener) elt.addEventListener ("click", function () alert ('button click'););  else if (elt.attachEvent) elt.attachEvent ("onclick", function () alert ('button click'););  else elt.onclick = function () alert ('botón pulsado'); ; 

Ahora las bibliotecas de JavaScript vienen con métodos de ayuda para hacer que la gestión de eventos sea más fácil de digerir. Por ejemplo, hacer lo anterior en jQuery es mucho más condensado..

 $ ("# myBtn"). haga clic en (función () alerta ('botón pulsado'););

Independientemente de su implementación, hay tres partes principales en los eventos:

  • Oyente: espera o 'escucha' a que se dispare un evento.
  • Dispatcher - activa el evento para disparar.
  • Manejador - función que se ejecutará cuando se dispare el evento.

En nuestro evento de clic al comienzo del tutorial, el oyente es el evento de clic que espera a que se haga clic en el elemento #myBtn. Cuando se hace clic en el elemento #myBtn, se despacha y se activa el controlador; que en este caso es una función anónima para mostrar el mensaje de alerta ().


Paso 1: Configuración de nuestra página

jQuery nos permite ir un paso más allá y crear nuestros propios eventos personalizados. En este tutorial, usaremos una lista desordenada de una lista de directorios y agregaremos funcionalidad a través de eventos personalizados que colapsarán y expandirán los directorios. Comencemos con nuestra estructura de página básica que se utilizará en los próximos ejemplos..

    Eventos personalizados de jQuery     
  • raíz/
    • index.html
    • about.html
    • galería.html
    • contact.html
    • bienes/
      • imagenes /
        • logo.png
        • fondo.jpg
      • js /
        • jquery.js
        • myscript.js
      • css /
        • page.css
        • typography.css

Aquí estamos creando una simple lista de directorios usando una lista desordenada. Hemos incluido jQuery de Google JSAPI CDN y hemos llamado addIcons (), que agrega imágenes de cada archivo y carpeta según la extensión de archivo enumerada. Esta función es puramente con fines estéticos. No es necesario para ninguno de los códigos de eventos personalizados que vamos a implementar. El resultado de este paso y se puede ver aquí..




Paso 2: .bind () y .trigger ()

Antes de comenzar a agregar eventos a nuestro ejemplo de listado de directorios, debemos comprender cómo funcionan .bind () y .trigger (). Usamos bind () para adjuntar un evento a todos los elementos coincidentes que residen actualmente en la página. Luego use .trigger () cuando desee enviar el evento. Echemos un vistazo a un ejemplo rápido..

 $ ("# myBtn"). bind ("click", function (evt) alert ('button clicked');); $ ("# myBtn"). trigger ("click");

En el código anterior, cuando se hace clic en el elemento con un id de 'myBtn', aparecerá un mensaje de alerta. Además, nuestro disparador () disparará el evento de clic inmediatamente cuando se carga la página. Solo tenga en cuenta que bind () es la forma en que adjunta un evento. Mientras .trigger (), está forzando que el evento se distribuya y ejecute el controlador del evento.


Paso 3: Eventos personalizados usando .bind () y .trigger ()

El método .bind () no solo se limita a los eventos del navegador, sino que se puede usar para implementar sus propios eventos personalizados. Comencemos creando eventos personalizados nombrados colapso y expandir para nuestro ejemplo de listado de directorios.

En primer lugar, vamos a unir colapso evento a todos los directorios representados en nuestra lista desordenada.

 $ ("# tree li: parent"). bind ("collapse", function (evt) 

Aquí encontramos todos los elementos que son padres y pasan el nombre del evento. colapso en el método .bind (). También hemos nombrado el primer parámetro. Evt, que representa el objeto Evento jQuery.

 $ (evt.target) .children (). slideUp (). end (). addClass ("contraído");

Ahora seleccionamos el objetivo del evento y subimos todos sus hijos. Además, tuvimos una clase de CSS colapsado a nuestro elemento de directorio.

 ). bind ("expandir", función (evt) 

Estamos encadenando eventos y uniendo nuestros expandir evento en esta linea.

 $ (evt.target) .children (). slideDown (). end (). removeClass ("colapso"); );

Justo lo contrario de nuestro colapso controlador de eventos, en el expandir En el controlador de eventos, deslizamos hacia abajo todos los elementos secundarios de los elementos del directorio y eliminamos la clase. colapsado de nuestro elemento objetivo. Poniendolo todo junto.

 $ ("# tree li: parent"). bind ("collapse", function (evt) $ (evt.target) .children (). slideUp (). end (). addClass ("collapsed");) .bind ("expandir", función (evt) $ (evt.target) .children (). slideDown (). end (). removeClass ("collapsed"););

Solo este código solo no hará nada por nosotros porque los eventos colapso y expandir son desconocidos y no tienen idea de cuándo ser enviado. Así que agregamos nuestro método .trigger () cuando queremos que estos eventos se activen..

 $ ("# tree li: parent"). bind ("collapse", function (evt) $ (evt.target) .children (). slideUp (). end (). addClass ("collapsed");) .bind ("expand", function (evt) $ (evt.target) .children (). slideDown (). end (). removeClass ("collapsed");)). toggle (function () // alternar entre $ (this) .trigger ("collapse");, function () $ (this) .trigger ("expand"););

Si ejecutamos este código, nuestros directorios ahora se alternarán cuando se haga clic entre ellos al disparar colapso y expandir evento. Pero, si hace clic en un directorio anidado, notará que nuestros eventos realmente se activan varias veces por clic. Esto es debido a un evento que burbujea.


Captura de eventos y burbujas

Cuando hace clic en un elemento de una página, el evento se desplaza, o se captura, desde el elemento superior que tiene un evento adjunto al destino deseado. Luego burbujea desde el objetivo intencionado de vuelta al padre superior.

Por ejemplo, cuando hacemos clic en la carpeta css /, nuestro evento se captura a través de root /, asset / y luego css /. Luego burbujea css /, asset /, luego a root /. Por lo tanto, el controlador se está ejecutando tres veces. Podemos corregir esto agregando un condicional simple en el controlador para el objetivo deseado.

 if (evt.target == evt.currentTarget) (evt.target) .children (). slideUp (). end (). addClass ("collapsed"); 

Este código verificará cada objetivo actual del evento con el objetivo previsto, o currentTarget. Cuando tengamos una coincidencia, solo entonces el script ejecutará el evento de colapso. Después de actualizar ambos colapso y expandir evento nuestra página funcionará como se espera.


Espacios de nombres de eventos

Un espacio de nombres proporciona contexto para eventos. Los eventos personalizados, colapso y expandir, son ambiguos La adición de un espacio de nombres a un evento personalizado de jQuery está estructurada nombre del evento Seguido por el espacio de nombres. Haremos nuestro espacio de nombres llamado TreeEvent, porque nuestros eventos representan las acciones y la funcionalidad de una estructura de carpetas de árbol. Una vez que hayamos agregado los espacios de nombres a nuestros eventos, el código ahora se verá así:

 $ ("# tree li: parent"). bind ("collapse.TreeEvent", function (evt) if (evt.target == evt.currentTarget) $ (evt.target) .children (). slideUp () .end (). addClass ("colapsado");). bind ("expand.TreeEvent", function (evt) if (evt.target == evt.currentTarget) $ (evt.target) .children ( ) .slideDown (). end (). removeClass ("colapso");). toggle (function () $ (this) .trigger ("collapse.TreeEvent");, function () $ (this ) .trigger ("expand.TreeEvent"););

Todo lo que necesitábamos cambiar eran los nombres de los eventos en los métodos .bind () y .trigger () para ambos colapso y expandir eventos. Ahora tenemos un ejemplo funcional usando eventos personalizados con espacios de nombre.

Tenga en cuenta que podemos eliminar fácilmente eventos de los elementos utilizando el método unbind ().

 $ ("# tree li: parent"). unbind ("collapse.TreeEvent"); // simplemente elimine el evento colapso $ ("# tree li: parent"). unbind (". TreeEvent"); // eliminar todos los eventos bajo el espacio de nombres TreeEvent


API de eventos especiales

Otra forma de configurar un evento personalizado en jQuery es aprovechar la API de eventos especiales. No hay mucha documentación sobre esta API, pero Brandom Aaron, un colaborador principal de jQuery, ha escrito dos excelentes publicaciones en el blog (http://brandonaaron.net/blog/2009/03/26/special-events y http: / /brandonaaron.net/blog/2009/06/4/jquery-edge-new-special-event-hooks) para ayudarnos a comprender los métodos disponibles. A continuación se muestra una breve explicación de los métodos..

  • agregar - similar a la configuración, pero se llama para cada evento que se está enlazando.
  • configuración: se llama cuando el evento está vinculado.
  • eliminar: es similar al desmontaje, pero se llama para cada evento que no está vinculado.
  • Desmontaje: se llama cuando el evento no está consolidado..
  • manejador - llamado cuando el evento es despachado.

Ahora, veamos cómo podemos combinar nuestros eventos personalizados en un Evento Especial al que llamaremos toggleCollapse.

 jQuery.event.special.toggleCollapse = setup: function (data, namespaces) for (var i en namespaces) if (namespaces [i] == "TreeEvent") jQuery (this) .bind ('click' jQuery.event.special.toggleCollapse.TreeEvent.handler); , teardown: function (namespaces) for (var i in namespaces) if (namespaces [i] == "TreeEvent") jQuery (this) .unbind ('click', jQuery.event.special.toggleCollapse .TreeEvent.handler); , TreeEvent: handler: function (event) if (event.target == event.currentTarget) var elt = jQuery (this); var cssClass = "colapsado"; if (elt.hasClass (cssClass)) elt.children (). slideDown (). end (). removeClass (cssClass);  else elt.children (). slideUp (). end (). addClass (cssClass);  event.type = "toggleCollapse"; jQuery.event.handle.apply (esto, argumentos); ; $ ("# tree li: parent"). bind ("toggleCollapse.TreeEvent", function (evt) );

Echémosle un vistazo sección por sección.

 jQuery.event.special.toggleCollapse = setup: function (data, namespaces) for (var i en namespaces) if (namespaces [i] == "TreeEvent") jQuery (this) .bind ('click', jQuery.event.special.toggleCollapse.TreeEvent.handler); ,

La primera linea jQuery.event.special.toggleCollapse crea un nuevo evento especial llamado toggleCollapse. Luego tenemos nuestro método de configuración, que se repite en todos los espacios de nombres de este evento. Una vez que encuentre TreeEvent, enlaza un evento de clic a los elementos coincidentes, que llamarán jQuery.event.special.toggleCollapse.TreeEvent.handler Una vez que se dispara el evento. Tenga en cuenta que estamos usando un evento de clic en oposición a la función toggle () que usamos en Eariler. Esto se debe a que toggle () no es un evento, sino una función auxiliar de interacción..

 teardown: function (namespaces) for (var i en namespaces) if (namespaces [i] == "TreeEvent") jQuery (this) .unbind ('click', jQuery.event.special.toggleCollapse.TreeEvent.handler ); ,

Nuestro método de desmontaje es similar a nuestro método de configuración, pero en su lugar, desenlazaremos el evento click de todos los elementos coincidentes.

 TreeEvent: handler: function (event) if (event.target == event.currentTarget) var elt = jQuery (this); var cssClass = "colapsado"; if (elt.hasClass (cssClass)) elt.children (). slideDown (). end (). removeClass (cssClass);  else elt.children (). slideUp (). end (). addClass (cssClass);  event.type = "toggleCollapse"; jQuery.event.handle.apply (esto, argumentos); ;

Aquí estamos usando el espacio de nombres TreeEvent para abstraer el controlador. En el controlador, alternamos entre un estado colapsado y expandido dependiendo de si el elemento coincidente contiene la clase CSS "colapsada". Por último, establecemos el tipo de evento a nuestro nombre de nuestro evento, toggleCollapse y use el método apply () que ejecutará el argumento de devolución de llamada cuando vinculemos este Evento Especial.

 $ ("# tree li: parent"). bind ("toggleCollapse.TreeEvent", function (evt) );

Finalmente, unimos nuestro Evento Especial a los directorios de nuestro listado de directorios. Nuestro resultado final se puede ver aquí..


Recursos Adicionales

A continuación, se incluyen algunos recursos adicionales que pueden resultarle útiles al trabajar con eventos personalizados. Gracias por leer!

  • API de eventos jQuery
  • Objeto de evento jQuery
  • Eventos personalizados en MooTools
  • Eventos personalizados en prototipo
  • Síganos en Twitter o suscríbase a Nettuts + RSS Feed para obtener los mejores tutoriales de desarrollo web en la web..