jQuery múltiples eventos para activar la misma función

977

¿Hay una manera de tener keyup, keypress, blur, y changeeventos llame a la misma función en una línea o tengo que hacer por separado?

El problema que tengo es que necesito validar algunos datos con una búsqueda de base de datos y me gustaría asegurarme de que la validación no se pierda en ningún caso, ya sea que esté escrita o pegada en el cuadro.

shaneburgess
fuente

Respuestas:

1794

Puede usar .on()para vincular una función a múltiples eventos:

$('#element').on('keyup keypress blur change', function(e) {
    // e.type is the type of event fired
});

O simplemente pase la función como parámetro a las funciones de eventos normales:

var myFunction = function() {
   ...
}

$('#element')
    .keyup(myFunction)
    .keypress(myFunction)
    .blur(myFunction)
    .change(myFunction)
Tatu Ulmanen
fuente
3
Con eventos separados por espacios, ¿cómo incluye también el espaciado de nombres? .on('keyup.foo keypress.foo blur.foo change.foo', …)o .on('keyup keypress blur change .foo', …)?
Sukima
24
El problema con esto es que probablemente llamarán a myFunction varias veces, lo que es posible que desee evitar.
Esger
2
¿Cómo puedo pasar el parámetro en esta función?
kushalvm
@ Esger De todos modos para hacer esto? En el móvil, siempre necesito hacerlo on('click tap', e => {...}). El oyente puede activarse dos veces, solo quiero disparar una vez, ¿cómo puedo codificar en la función del oyente?
Tomision
99
@Tomlsion Quizás agregue un className 'busy' al elemento en la función llamada, y luego $('#element:not(.busy)').on('keyup keypress blur change', function(e){…});finalmente elimine el className 'busy'.
Esger
60

A partir de jQuery 1.7, el .on()método es el método preferido para adjuntar controladores de eventos a un documento. Para versiones anteriores, el .bind()método se utiliza para adjuntar un controlador de eventos directamente a los elementos.

$(document).on('mouseover mouseout',".brand", function () {
  $(".star").toggleClass("hovered");
})
lesyk
fuente
1
Esto se hace para un evento delegado, funcionará, pero no es la forma más sencilla de hacerlo, ni la más eficiente.
Ben Taliadoros
1
La delegación de eventos es importante, y puede (o no) ser necesaria dependiendo de cuándo se carga / ejecuta el script, y si los elementos existen en el DOM en el momento en que se carga / ejecuta el script.
random_user_name
45

Estaba buscando una forma de obtener el tipo de evento cuando jQuery escucha varios eventos a la vez, y Google me puso aquí.

Entonces, para los interesados, event.typees mi respuesta:

$('#element').on('keyup keypress blur change', function(event) {
    alert(event.type); // keyup OR keypress OR blur OR change
});

Más información en el documento jQuery .

Alain Tiemblo
fuente
24

Puede usar el método de vinculación para adjuntar funciones a varios eventos. Simplemente pase los nombres de los eventos y la función del controlador como en este código:

$('#foo').bind('mouseenter mouseleave', function() {
  $(this).toggleClass('entered');
});

Otra opción es usar el soporte de encadenamiento de jquery api.

Giorgi
fuente
99
A partir de jQuery 1.7, el método .on () es el método preferido para adjuntar controladores de eventos a un documento.
Dzhuneyt
18

Si adjunta el mismo controlador de eventos a varios eventos, a menudo se topa con el problema de que más de uno de ellos se dispare a la vez (por ejemplo, el usuario presiona la pestaña después de la edición; la tecla, el cambio y el desenfoque podrían dispararse).

Parece que lo que realmente quieres es algo como esto:

$('#ValidatedInput').keydown(function(evt) {
  // If enter is pressed
  if (evt.keyCode === 13) {
    evt.preventDefault();

    // If changes have been made to the input's value, 
    //  blur() will result in a change event being fired.
    this.blur();
  }
});

$('#ValidatedInput').change(function(evt) {
  var valueToValidate = this.value;

  // Your validation callback/logic here.
});
Dave Ward
fuente
14

Así es como lo hago.

$("input[name='title']").on({
    "change keyup": function(e) {
        var slug = $(this).val().split(" ").join("-").toLowerCase();
        $("input[name='slug']").val(slug);
    },
});
Sajjad Ashraf
fuente
11

Puede definir la función que desea reutilizar de la siguiente manera:

var foo = function() {...}

Y luego puede configurar la cantidad de oyentes de eventos que desee en su objeto para activar esa función usando on ('evento') dejando un espacio intermedio como se muestra a continuación:

$('#selector').on('keyup keypress blur change paste cut', foo);
Codificador De La Galaxia
fuente
3
Generalmente deberías explicar tu respuesta. Simplemente pegar código no ayuda a que el OP entienda su problema o su solución.
leigero
¿Qué sucede si necesito el primer argumento en la función de suscriptor de eventos jquery (evento)? ¿Cómo usarlo?
Dr.X
Está bien, puede declarar la función con el parámetro de evento y luego acceder a ella desde el método. Estos eventos pasarán el objeto en sí mismos. Espero que esto ayude. var foo = función (evento) {console.log (evento); } $ ('# selector'). on ('keyup keypress blur cambiar pegar cortar', foo);
Coder Of The Galaxy
7

La respuesta de Tatu es cómo lo haría intuitivamente, pero he experimentado algunos problemas en Internet Explorer con esta forma de anidar / vincular los eventos, a pesar de que se hace a través del .on()método.

No he podido determinar exactamente con qué versiones de jQuery este es el problema. Pero a veces veo el problema en las siguientes versiones:

  • 2.0.2
  • 1.10.1
  • 1.6.4
  • Mobile 1.3.0b1
  • Mobile 1.4.2
  • Mobile 1.2.0

Mi solución ha sido definir primero la función,

function myFunction() {
    ...
}

y luego manejar los eventos individualmente

// Call individually due to IE not handling binds properly
$(window).on("scroll", myFunction);
$(window).on("resize", myFunction);

Esta no es la solución más bonita, pero funciona para mí, y pensé que lo pondría a disposición para ayudar a otros que podrían tropezar con este problema

Squazz
fuente
5
$("element").on("event1 event2 event..n", function() {
   //execution
});

Este tutorial trata sobre el manejo de múltiples eventos.

Invitado
fuente
4

¿Hay una manera de tener keyup, keypress, blur, y changeeventos llame a la misma función en una línea?

Es posible usar .on(), que acepta la siguiente estructura:, .on( events [, selector ] [, data ], handler )por lo que puede pasar múltiples eventos a este método. En su caso, debería verse así:

$('#target').on('keyup keypress blur change', function(e) {
    // "e" is an event, you can detect the type of event using "e.type"
});

Y aquí está el ejemplo en vivo:

$('#target').on('keyup keypress blur change', function(e) {
  console.log(`"${e.type.toUpperCase()}" event happened`)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="target">

Suicidio comercial
fuente
2

Es simple implementar esto con los métodos DOM integrados sin una gran biblioteca como jQuery, si lo desea, solo se necesita un poco más de código: itere sobre una matriz de nombres de eventos y agregue un escucha para cada uno:

function validate() {
  // ...
}

const element = document.querySelector('#element');
['keyup', 'keypress', 'blur', 'change'].forEach((eventName) => {
  element.addEventListener(eventName, validate);
});
Cierto rendimiento
fuente