Buscar..


Observaciones

jQuery maneja internamente eventos a través de la función addEventListener . Esto significa que es perfectamente legal tener más de una función vinculada al mismo evento para el mismo elemento DOM.

Adjuntar y separar controladores de eventos

Adjuntar un controlador de eventos

Desde la versión 1.7 jQuery tiene el evento API .on() . De esta manera, cualquier evento javascript estándar o evento personalizado se puede vincular al elemento jQuery seleccionado actualmente. Existen accesos directos como .click() , pero .on() le ofrece más opciones.


HTML

<button id="foo">bar</button>

jQuery

$( "#foo" ).on( "click", function() {
  console.log( $( this ).text() ); //bar
});

Separar un controlador de eventos

Naturalmente, también tiene la posibilidad de separar eventos de sus objetos jQuery. Lo hace utilizando .off( events [, selector ] [, handler ] ) .


HTML

<button id="hello">hello</button>

jQuery

$('#hello').on('click', function(){
    console.log('hello world!');
    $(this).off();
});

Al hacer clic en el botón $(this) se referirá al objeto jQuery actual y eliminará de él todos los controladores de eventos adjuntos. También puede especificar qué controlador de eventos debe eliminarse.

jQuery

$('#hello').on('click', function(){
    console.log('hello world!');
    $(this).off('click');
});

$('#hello').on('mouseenter', function(){
    console.log('you are about to click');
});

En este caso, el evento mouseenter seguirá funcionando después de hacer clic.

Eventos delegados

Vamos a empezar con el ejemplo. Aquí hay un ejemplo muy simple de HTML.

Ejemplo HTML

<html>
    <head>
    </head>
    <body>
        <ul>
            <li>
                <a href="some_url/">Link 1</a>
            </li>
            <li>
                <a href="some_url/">Link 2</a>
            </li>
            <li>
                <a href="some_url/">Link 3</a>
            </li>
        </ul>
    </body>
</html>

El problema

Ahora, en este ejemplo, queremos agregar un detector de eventos a todos los elementos <a> . El problema es que la lista en este ejemplo es dinámica. <li> elementos se agregan y eliminan a medida que pasa el tiempo. Sin embargo, la página no se actualiza entre los cambios, lo que nos permitiría utilizar escuchas de eventos de clic simple para los objetos de enlace (es decir, $('a').click() ).

El problema que tenemos es cómo agregar eventos a los elementos <a> que van y vienen.


Información de fondo - propagación de eventos

Los eventos delegados solo son posibles debido a la propagación de eventos (a menudo llamada propagación de eventos). Cada vez que se activa un evento, se propagará hasta el final (a la raíz del documento). Delegan el manejo de un evento a un elemento ancestral que no cambia, de ahí el nombre de eventos "delegados".

Entonces, en el ejemplo anterior, al hacer clic en el enlace del elemento <a> se activará el evento 'clic' en estos elementos en este orden:

  • una
  • li
  • ul
  • cuerpo
  • html
  • Raiz del documento

Solución

Sabiendo qué hace el burbujeo de eventos, podemos detectar uno de los eventos deseados que se están propagando a través de nuestro HTML.

Un buen lugar para capturarlo en este ejemplo es el elemento <ul> , ya que ese elemento no es dinámico:

$('ul').on('click', 'a', function () {
  console.log(this.href); // jQuery binds the event function to the targeted DOM element
                          // this way `this` refers to the anchor and not to the list
  // Whatever you want to do when link is clicked
});

En lo anterior:

  • Tenemos 'ul' que es el receptor de este detector de eventos.
  • El primer parámetro ('clic') define qué eventos estamos tratando de detectar.
  • El segundo parámetro ('a') se usa para declarar desde dónde se debe originar el evento (de todos los elementos secundarios bajo el destinatario del oyente del evento, ul).
  • Por último, el tercer parámetro es el código que se ejecuta si se cumplen los requisitos del primer y segundo parámetro.

En detalle cómo funciona la solución.

  1. El usuario hace clic en el elemento <a>
  2. Eso activa el evento de clic en el elemento <a> .
  3. El evento comienza a burbujear hacia la raíz del documento.
  4. El evento burbujea primero en el elemento <li> y luego en el elemento <ul> .
  5. La escucha de eventos se ejecuta ya que el elemento <ul> tiene adjunta la escucha de eventos.
  6. El detector de eventos primero detecta el evento desencadenante. El evento de propagación es "clic" y el oyente tiene "clic", es un pase.
  7. Las comprobaciones de escucha intentan hacer coincidir el segundo parámetro ('a') con cada elemento de la cadena de burbujas. Como el último elemento de la cadena es una 'a', esto coincide con el filtro y también es un pase.
  8. El código en el tercer parámetro se ejecuta utilizando el elemento coincidente, ya que es this . Si la función no incluye una llamada a stopPropagation() , el evento continuará propagándose hacia la raíz ( document ).

Nota: Si un antecesor adecuado que no cambia no está disponible / conveniente, debe usar el document . Como hábito no use 'body' por las siguientes razones:

  • body tiene un error, que tiene que ver con el estilo, que puede significar que los eventos del mouse no le hagan burbujas. Esto depende del navegador y puede ocurrir cuando la altura del cuerpo calculada es 0 (por ejemplo, cuando todos los elementos secundarios tienen posiciones absolutas). Los eventos del ratón siempre burbujean para document .
  • document siempre existe en su secuencia de comandos, por lo que puede adjuntar controladores delegados para document fuera de un controlador listo para DOM y asegurarse de que todavía funcionarán.

Evento de carga de documentos .load ()

Si desea que su secuencia de comandos espere hasta que se cargue un determinado recurso, como una imagen o un PDF, puede usar .load() , que es un atajo para el acceso directo de .on( "load", handler) .

HTML

<img src="image.jpeg" alt="image" id="image">

jQuery

$( "#image" ).load(function() {
  // run script
});

Eventos para repetir elementos sin usar ID's.

Problema

Hay una serie de elementos repetidos en la página en los que necesita saber en qué evento ocurrió para hacer algo con esa instancia específica.

Solución

  • Dar a todos los elementos comunes una clase común
  • Aplicar el detector de eventos a una clase. this controlador de eventos interno es el elemento selector correspondiente en el que ocurrió el evento
  • Recorra el contenedor externo más repetitivo para esa instancia comenzando en this
  • Use find() dentro de ese contenedor para aislar otros elementos específicos de esa instancia

HTML

<div class="item-wrapper" data-item_id="346">
   <div class="item"><span class="person">Fred</span></div>
   <div class="item-toolbar">
      <button class="delete">Delete</button>
   </div>   
</div>
<div class="item-wrapper" data-item_id="393">
   <div clss="item"><span class="person">Wilma</span></div>
   <div class="item-toolbar">
      <button class="delete">Delete</button>
   </div>   
</div>

jQuery

$(function() {
  $('.delete').on('click', function() {
    // "this" is element event occured on
    var $btn = $(this);
    // traverse to wrapper container
    var $itemWrap = $btn.closest('.item-wrapper');
    // look within wrapper to get person for this button instance
    var person = $itemWrap.find('.person').text();
    // send delete to server and remove from page on success of ajax
    $.post('url/string', { id: $itemWrap.data('item_id')}).done(function(response) {
      $itemWrap.remove()
    }).fail(function() {
      alert('Ooops, not deleted at server');
    });
  });
});

originalEvento

A veces habrá propiedades que no están disponibles en el evento jQuery. Para acceder a las propiedades subyacentes use Event.originalEvent

Obtener la dirección de desplazamiento

$(document).on("wheel",function(e){
    console.log(e.originalEvent.deltaY)
    // Returns a value between -100 and 100 depending on the direction you are scrolling
})

Activar y desactivar eventos específicos a través de jQuery. (Oyentes nombrados)

A veces desea desactivar todos los oyentes registrados previamente.

//Adding a normal click handler
$(document).on("click",function(){
    console.log("Document Clicked 1")
});
//Adding another click handler
$(document).on("click",function(){
    console.log("Document Clicked 2")
});
//Removing all registered handlers.
$(document).off("click")

Un problema con este método es que TODOS los escuchas vinculados en el document por otros complementos, etc., también serían eliminados.

La mayoría de las veces, deseamos separar a todos los oyentes conectados solo por nosotros.

Para lograr esto, podemos unir a oyentes nombrados como,

//Add named event listener.
$(document).on("click.mymodule",function(){
    console.log("Document Clicked 1")
});
$(document).on("click.mymodule",function(){
    console.log("Document Clicked 2")
});

//Remove named event listener.
$(document).off("click.mymodule");

Esto asegura que cualquier otro detector de clics no se modifique inadvertidamente.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow