1124

Is there a way to have keyup, keypress, blur, and change events call the same function in one line or do I have to do them separately?

The problem I have is that I need to validate some data with a db lookup and would like to make sure validation is not missed in any case, whether it is typed or pasted into the box.

13 Answers 13

2059

You can use .on() to bind a function to multiple events:

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

Or just pass the function as the parameter to normal event functions:

var myFunction = function() {
   ...
}

$('#element')
    .keyup(myFunction)
    .keypress(myFunction)
    .blur(myFunction)
    .change(myFunction)
10
  • 5
    With space separated events how do you also include name spacing? .on('keyup.foo keypress.foo blur.foo change.foo', …) or .on('keyup keypress blur change .foo', …)?
    – Sukima
    Commented Dec 14, 2015 at 14:48
  • 30
    Problem with this is that myFunction will probably get called multiple times, which you might want to prevent.
    – Esger
    Commented Jan 21, 2016 at 9:51
  • 2
    How can I pass parameter in this function?
    – HalfWebDev
    Commented May 26, 2016 at 7:45
  • 1
    @Esger Anyway to do this? In mobile, I always need to on('click tap', e => {...}). The listener may be triggered twice, I just wanna trigger once, how can I code in the listener function?
    – tomision
    Commented Nov 10, 2016 at 14:34
  • 9
    @Tomlsion Maybe add a className 'busy' to the element in the called function, and then $('#element:not(.busy)').on('keyup keypress blur change', function(e){…}); Finally remove the className 'busy'.
    – Esger
    Commented Dec 4, 2016 at 21:57
70

As of jQuery 1.7, the .on() method is the preferred method for attaching event handlers to a document. For earlier versions, the .bind() method is used for attaching an event handler directly to elements.

$(document).on('mouseover mouseout',".brand", function () {
  $(".star").toggleClass("hovered");
})
2
  • 1
    This is done for a delegated event, it will work, but it's not the simplest way of doing it, nor the most efficient. Commented Apr 8, 2014 at 15:19
  • 1
    Event delegation is important, and may (or may not) be required depending on when the script is loaded / run, and if the elements exist in the DOM at the time the script is loaded / run. Commented Jan 11, 2017 at 16:57
61

I was looking for a way to get the event type when jQuery listens for several events at once, and Google put me here.

So, for those interested, event.type is my answer :

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

More info in the jQuery doc.

1
  • What if I want to use and between events instead of or. So that if both events occur then trigger this function? Commented May 13, 2022 at 18:29
27

You can use bind method to attach function to several events. Just pass the event names and the handler function as in this code:

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

Another option is to use chaining support of jquery api.

1
  • 12
    As of jQuery 1.7, the .on() method is the preferred method for attaching event handlers to a document.
    – Dzhuneyt
    Commented Aug 25, 2013 at 18:25
24

Is there a way to have keyup, keypress, blur, and change events call the same function in one line?

It's possible using .on(), which accepts the following structure: .on( events [, selector ] [, data ], handler ), so you can pass multiple events to this method. In your case it should look like this:

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

And here is the live example:

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

18

If you attach the same event handler to several events, you often run into the issue of more than one of them firing at once (e.g. user presses tab after editing; keydown, change, and blur might all fire).

It sounds like what you actually want is something like this:

$('#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.
});
15

This is how i do it.

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

You could define the function that you would like to reuse as below:

var foo = function() {...}

And later you can set however many event listeners you want on your object to trigger that function using on('event') leaving a space in between as shown below:

$('#selector').on('keyup keypress blur change paste cut', foo);
3
  • 3
    Generally you should explain your answer. Simply pasting code does nothing to help the OP understand their problem or your solution.
    – leigero
    Commented Apr 8, 2015 at 18:06
  • what if I need first argument in jquery event subscriber function (event)? How to use it? Commented Sep 14, 2018 at 6:32
  • That's ok, you can just declare the function with the event parameter and then access it from within the method. These events will pass the object in themselves. I hope this helps. var foo = function(event) { console.log(event); } $('#selector').on('keyup keypress blur change paste cut', foo); Commented Sep 17, 2018 at 14:00
7

The answer by Tatu is how I would intuitively do it, but I have experienced some problems in Internet Explorer with this way of nesting/binding the events, even though it is done through the .on() method.

I havn't been able to pinpoint exactly which versions of jQuery this is the problem with. But I sometimes see the problem in the following versions:

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

My workaround have been to first define the function,

function myFunction() {
    ...
}

and then handle the events individually

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

This is not the prettiest solution, but it works for me, and I thought I would put it out there to help others that might stumble upon this issue

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

This tutorial is about handling multiple events.

4

It's simple to implement this with the built-in DOM methods without a big library like jQuery, if you want, it just takes a bit more code - iterate over an array of event names, and add a listener for each:

function validate(event) {
  // ...
}

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

If you'd want to mimic adding to more than 1 element:

const elements = document.querySelectorAll('.commonSelector');
['keyup', 'keypress', 'blur', 'change'].forEach((eventName) => {
  elements.forEach(element => {
      element.addEventListener(eventName, validate);
  });
});
1
  • Note that jQuery does nothing less - in the end it itself goes down to return elem.each( function() { jQuery.event.add( this, types, fn, data, selector ); } ); (this is straight from jQuery 3.6.0 code)
    – jave.web
    Commented Aug 20, 2022 at 10:18
4

Instead of:

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

You can use:

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

input is trigerred for keyup keypress blur change events even for paste!

0

But to prevent multiple triggering:

var a;
var foo = function() {
    clearTimeout(a);
    a=setTimeout(function(){
        //your code
        console.log("Runned")
    },50);
}
$('textarea').on('blur change', foo);

Not the answer you're looking for? Browse other questions tagged or ask your own question.