jQuery vários eventos para disparar a mesma função

977

Existe uma maneira de ter keyup, keypress, blur, e changeeventos chamam a mesma função em uma linha ou eu tenho que fazê-las separadamente?

O problema que tenho é que preciso validar alguns dados com uma pesquisa de banco de dados e gostaria de garantir que a validação não seja perdida em nenhum caso, seja digitada ou colada na caixa.

shaneburgess
fonte

Respostas:

1794

Você pode usar .on()para vincular uma função a vários eventos:

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

Ou apenas passe a função como parâmetro para funções normais de eventos:

var myFunction = function() {
   ...
}

$('#element')
    .keyup(myFunction)
    .keypress(myFunction)
    .blur(myFunction)
    .change(myFunction)
Tatu Ulmanen
fonte
3
Com eventos separados por espaço, como você também inclui espaçamento de nome? .on('keyup.foo keypress.foo blur.foo change.foo', …)ou .on('keyup keypress blur change .foo', …)?
Sukima
24
O problema é que o myFunction provavelmente será chamado várias vezes, o que você pode querer impedir.
Esger
2
Como posso passar parâmetro nesta função?
Kushalvm
@ Esger De qualquer maneira, para fazer isso? No celular, eu sempre preciso on('click tap', e => {...}). O ouvinte pode ser acionado duas vezes, eu só quero acionar uma vez, como posso codificar na função de ouvinte?
tomision
9
@ Tomlion Talvez adicione um className 'busy' ao elemento na função chamada e, $('#element:not(.busy)').on('keyup keypress blur change', function(e){…});finalmente, remova o className 'busy'.
Esger
60

A partir do jQuery 1.7, o .on()método é o método preferido para anexar manipuladores de eventos a um documento. Para versões anteriores, o .bind()método é usado para anexar um manipulador de eventos diretamente aos elementos.

$(document).on('mouseover mouseout',".brand", function () {
  $(".star").toggleClass("hovered");
})
lesyk
fonte
1
Isso é feito para um evento delegado, funcionará, mas não é a maneira mais simples de fazê-lo, nem a mais eficiente.
Ben Taliadoros
1
A delegação de eventos é importante e pode (ou não) ser necessária, dependendo de quando o script for carregado / executado e se os elementos existirem no DOM no momento em que o script for carregado / executado.
random_user_name
45

Eu estava procurando uma maneira de obter o tipo de evento quando o jQuery ouve vários eventos ao mesmo tempo, e o Google me colocou aqui.

Então, para os interessados, event.typeé a minha resposta:

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

Mais informações no documento jQuery .

Alain Tiemblo
fonte
24

Você pode usar o método bind para anexar a função a vários eventos. Basta passar os nomes dos eventos e a função manipuladora, como neste código:

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

Outra opção é usar o suporte de encadeamento da jquery api.

Giorgi
fonte
9
A partir do jQuery 1.7, o método .on () é o método preferido para anexar manipuladores de eventos a um documento.
Dzhuneyt 25/08
18

Se você anexa o mesmo manipulador de eventos a vários eventos, geralmente encontra o problema de mais de um deles disparar de uma só vez (por exemplo, o usuário pressiona a guia após a edição; todas as teclas pressionadas, alteradas e desfocadas podem disparar).

Parece que o que você realmente deseja é algo como isto:

$('#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
fonte
14

É assim que eu faço.

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

Você pode definir a função que gostaria de reutilizar como abaixo:

var foo = function() {...}

E mais tarde, você pode definir quantos ouvintes de eventos desejar no seu objeto para acionar essa função usando on ('event'), deixando um espaço no meio, como mostrado abaixo:

$('#selector').on('keyup keypress blur change paste cut', foo);
Codificador da galáxia
fonte
3
Geralmente você deve explicar sua resposta. Simplesmente colar código não ajuda a OP a entender o problema ou a sua solução.
Leitero
e se eu precisar do primeiro argumento na função de assinante de evento jquery (evento)? Como usá-lo?
Dr.X
Tudo bem, você pode simplesmente declarar a função com o parâmetro event e acessá-la de dentro do método Esses eventos passarão o objeto em si mesmos. Eu espero que isso ajude. var foo = função (evento) {console.log (evento); } $ ('# selector'). on ('keyup keypress borrão alterar colar cortar', foo);
Coder Of The Galaxy
7

A resposta de Tatu é como eu o faria intuitivamente, mas tive alguns problemas no Internet Explorer com essa maneira de aninhar / vincular os eventos, mesmo que isso seja feito através do .on()método.

Não consegui identificar exatamente com quais versões do jQuery esse é o problema. Mas às vezes vejo o problema nas seguintes versões:

  • 2.0.2
  • 1.10.1
  • 1.6.4
  • Mobile 1.3.0b1
  • Móvel 1.4.2
  • Mobile 1.2.0

Minha solução alternativa foi definir primeiro a função,

function myFunction() {
    ...
}

e depois manipular os eventos individualmente

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

Essa não é a solução mais bonita, mas funciona para mim, e eu pensei em divulgá-la para ajudar outras pessoas que possam se deparar com esse problema.

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

Este tutorial é sobre como lidar com vários eventos.

Hóspede
fonte
4

Existe uma maneira de ter keyup, keypress, blur, e changeeventos chamam a mesma função em uma linha?

É possível usar .on(), que aceita a seguinte estrutura:, .on( events [, selector ] [, data ], handler )para que você possa passar vários eventos para esse método. No seu caso, deve ficar assim:

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

E aqui está o exemplo ao 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">

Suicídio Comercial
fonte
2

É simples implementar isso com os métodos DOM internos, sem uma grande biblioteca como o jQuery; se você quiser, é preciso um pouco mais de código - repita uma matriz de nomes de eventos e adicione um ouvinte para cada:

function validate() {
  // ...
}

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