Events are how a page reacts to people: a click, a key press, the mouse moving over a card, a form being sent. jQuery gives you one main method for all of them, .on(), plus a few helpers around it. If you have read JavaScript Events, the ideas behind jQuery events are the same – jQuery mostly shortens the code and makes event delegation very easy.
Attaching a handler with .on()
The basic way to handle jQuery events is $(selector).on(eventName, handler). The handler is a function that jQuery calls each time the event happens, on each matched element. You can list several event names separated by spaces to share one handler.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Click, mouseenter and mouseleave</title>
<style>
body { font-family: system-ui, sans-serif; padding: 16px; line-height: 1.5; }
.card { display: inline-block; width: 140px; margin: 6px; padding: 12px; border: 2px solid #ccc; border-radius: 8px; cursor: pointer; }
.card.active { border-color: #0a7a3d; background: #e8f6ee; }
.card.hover { box-shadow: 0 2px 8px rgba(0, 0, 0, .2); }
</style>
</head>
<body>
<div class="card" data-plan="Basic">Basic plan</div>
<div class="card" data-plan="Standard">Standard plan</div>
<div class="card" data-plan="Premium">Premium plan</div>
<p id="log">Hover over a plan, then click one.</p>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
const $cards = $('.card');
// One handler for two events: event.type tells you which one fired
$cards.on('mouseenter mouseleave', (event) => {
$(event.currentTarget).toggleClass('hover', event.type === 'mouseenter');
});
$cards.on('click', (event) => {
const $card = $(event.currentTarget);
$cards.removeClass('active');
$card.addClass('active');
$('#log').text(`You chose the ${$card.attr('data-plan')} plan.`);
});
</script>
</body>
</html>Tip: In this demo the cards are <div> elements only to show mouse events. For real clickable controls use <button>, which works with the keyboard and screen readers for free.
Shorthand methods are deprecated
Older code often uses shortcuts like .click(fn), .hover(fnIn, fnOut), .keyup(fn) or .submit(fn). These were deprecated in jQuery 3.3. They still exist, but write .on('click', fn) in new code – it is one consistent pattern and it supports delegation and namespaces. Also avoid the even older .bind(), .unbind(), .delegate() and .undelegate(): they have been deprecated since jQuery 3.0 and are replaced by .on() and .off().
jQuery events you will use most
| Event name | Fires when… |
|---|---|
click | An element is clicked or tapped, or a focused button is activated with Enter or Space |
input | The value of a text field, textarea or select changes – on every keystroke |
change | A value is committed, such as ticking a checkbox or choosing from a select |
submit | A form is sent; listen on the <form>, not the button |
keydown | A key is pressed; check event.key, for example 'Enter' |
mouseenter / mouseleave | The pointer moves onto or off an element (they do not bubble from children) |
focus / blur | An element gains or loses keyboard focus |
jQuery events use the browser’s own names, without the “on” prefix. jQuery does not invent new events here; it simply gives you one way to listen for all of them, and it works the same on every element in the set.
The event object, this and arrow functions
jQuery passes an event object to your handler. It is a jQuery wrapper around the browser’s event with the same familiar properties: event.type, event.target (where the event started), event.currentTarget (the element whose handler is running), event.key for keyboard events and event.preventDefault(). The original browser event is in event.originalEvent if you ever need it.
Inside a normal function handler, jQuery also sets this to the current element, so old code is full of $(this). Arrow functions do not get their own this, so with an arrow function use $(event.currentTarget) instead. Both styles are correct; just do not mix them up.
// Classic function: this = the clicked button
$('.like').on('click', function () {
$(this).addClass('liked');
});
// Arrow function: use event.currentTarget instead of this
$('.like').on('click', (event) => {
$(event.currentTarget).addClass('liked');
});Stopping default actions
Links navigate and forms reload the page. Call event.preventDefault() to cancel that default action. You may also see return false; at the end of jQuery handlers. In jQuery that does two things – it prevents the default and stops the event bubbling to parent elements – which can quietly break other code listening higher up. Prefer calling preventDefault() explicitly so your intent is clear.
Event delegation
A handler added with $('.item').on('click', …) is attached only to items that exist at that moment. Items added later get nothing. The fix is delegation: attach one handler to a parent that always exists and give .on() a selector as the second argument. Because events bubble up, the parent hears clicks from all current and future children, and jQuery only calls your handler when the click came from an element matching the selector. You will use this in jQuery Add and Remove Elements.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>A delegated to-do list</title>
<style>
body { font-family: system-ui, sans-serif; padding: 16px; line-height: 1.5; }
li { margin: 4px 0; }
li.done span { text-decoration: line-through; color: #777; }
.remove { margin-left: 8px; }
</style>
</head>
<body>
<form id="add-form">
<label for="task">New task</label>
<input id="task" type="text" value="Book train tickets to Madurai">
<button type="submit">Add</button>
</form>
<ul id="todo">
<li><span>Pay electricity bill</span><button type="button" class="remove">✕</button></li>
</ul>
<p id="count"></p>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
const $list = $('#todo');
function updateCount() {
$('#count').text(`${$list.children().length} task(s) on the list.`);
}
$('#add-form').on('submit', (event) => {
event.preventDefault(); // no page reload
const text = $('#task').val().trim();
if (!text) return;
const $li = $('<li>').append($('<span>').text(text), $('<button type="button" class="remove">✕</button>'));
$list.append($li);
$('#task').val('');
updateCount();
});
// Delegated: works for the first item AND every item added later
$list.on('click', 'span', (event) => {
$(event.currentTarget).parent().toggleClass('done');
});
$list.on('click', '.remove', (event) => {
$(event.currentTarget).parent().remove();
updateCount();
});
updateCount();
</script>
</body>
</html>In a delegated handler, event.currentTarget (and this) is the matched child – here the clicked <span> or button – while event.delegateTarget is the list the handler is attached to.
One-time handlers, .off() and namespaces
.one('click', fn)runs the handler at most once per element, then removes it – useful for “claim your coupon” style buttons..off('click')removes click handlers. Pass the same function to.off('click', fn)to remove just that one.- A namespace such as
'click.menu'labels your handler. Later,.off('.menu')removes only handlers with that label, leaving other scripts’ handlers alone. .trigger('click')runs the handlers for an event from code, as if it had happened.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>.one() and namespaced .off()</title>
<style>
body { font-family: system-ui, sans-serif; padding: 16px; line-height: 1.5; }
</style>
</head>
<body>
<button id="coupon" type="button">Claim 10% coupon</button>
<button id="tip" type="button">Show tip</button>
<button id="stop-tips" type="button">Stop tips</button>
<p id="msg">Each button shows a message here.</p>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
let tips = 0;
$('#coupon').one('click', () => {
$('#msg').text('Coupon CHAI10 added. Clicking again does nothing.');
});
$('#tip').on('click.tips', () => {
tips++;
$('#msg').text(`Tip ${tips}: drink water every hour.`);
});
$('#stop-tips').on('click', () => {
$('#tip').off('.tips'); // remove only the namespaced handler
$('#msg').text('Tips switched off.');
});
</script>
</body>
</html>