Events
Binding events with .on(), event delegation for dynamic content, and common event types.
Binding events with .on()
.on() is jQuery's unified method for attaching event handlers — it replaced older, more specialized methods (.bind(), .live(), .delegate()) from earlier jQuery versions:
$('#save-btn').on('click', function () {
console.log('Save clicked');
});
$('#search-input').on('keyup', function () {
console.log('Current value:', $(this).val());
});
$('#signup-form').on('submit', function (event) {
event.preventDefault(); // stop the browser's default full-page form submission
console.log('Form submitted via AJAX instead');
});
Inside a handler, this refers to the raw DOM element the event fired on — wrap it in $(this) to use jQuery methods on it.
Common events
| Event | Fires when |
|---|---|
click |
An element is clicked |
submit |
A <form> is submitted |
keyup / keydown |
A key is released / pressed, while an element has focus |
change |
A form field's value changes and it loses focus (or immediately, for checkboxes/selects) |
input |
A form field's value changes, fired on every keystroke |
mouseenter / mouseleave |
The pointer enters / leaves an element (doesn't bubble to children, unlike mouseover/mouseout) |
focus / blur |
An element gains / loses keyboard focus |
Event delegation
Event delegation attaches a single handler to a stable ancestor element, and listens for events bubbling up from descendants that match a selector — instead of attaching a separate handler to every individual descendant. This matters most for elements added to the page after the page first loads, since a handler bound directly to an element that doesn't exist yet simply never fires for it.
<ul id="todo-list">
<li>Buy milk <button class="delete-btn">Delete</button></li>
<li>Walk the dog <button class="delete-btn">Delete</button></li>
</ul>
<button id="add-item">Add item</button>
// WRONG for dynamic content — only binds to buttons that exist right now
$('.delete-btn').on('click', function () {
$(this).closest('li').remove();
});
// RIGHT — delegated from a stable ancestor that already exists on page load
$('#todo-list').on('click', '.delete-btn', function () {
$(this).closest('li').remove();
});
$('#add-item').on('click', function () {
$('#todo-list').append('<li>New task <button class="delete-btn">Delete</button></li>');
});
With the delegated version, clicking "Add item" creates a brand-new <li> with its own .delete-btn — and clicking that button still works, even though it didn't exist when the page loaded, because #todo-list (the element the handler is actually bound to) was always there. jQuery checks, at click time, whether the actual clicked element matches .delete-btn, and only then runs the handler.
Removing handlers
function handleClick() {
console.log('clicked');
}
$('#btn').on('click', handleClick);
$('#btn').off('click', handleClick); // removes just this specific handler
$('#btn').off('click'); // removes every click handler on this element
Triggering events programmatically
$('#save-btn').trigger('click'); // fires the click handler(s) as if a user clicked
Useful in tests, or to reuse the same logic (e.g. programmatically "clicking" a hidden file input from a styled button).
Namespaced events
Attaching a custom namespace to an event lets you remove a specific group of handlers without disturbing others bound to the same event type:
$('#panel').on('click.tooltipPlugin', function () { /* ... */ });
$('#panel').on('click.myApp', function () { /* ... */ });
$('#panel').off('click.tooltipPlugin'); // removes only that namespace's handler
Common mistakes
- Binding handlers directly to elements that are added to the page dynamically (via AJAX, or created in JavaScript) instead of using delegation from a stable ancestor — the handler silently never fires because it was never attached to an element that didn't exist yet.
- Forgetting
event.preventDefault()in a form'ssubmithandler when the intent is to handle the submission via AJAX — without it, the browser still performs its default full-page navigation/submit alongside your handler. - Attaching the same handler multiple times (e.g. by re-running setup code on every AJAX page update) without first calling
.off(), causing a click to fire the handler two, three, or more times.