jQuery provides a comprehensive and type-safe event system for handling user interactions, custom events, and asynchronous operations. The TypeScript definitions include detailed event types and handler signatures.
interface JQuery<TElement = HTMLElement> {
// Attach event handlers
on(events: string, handler: JQuery.TypeEventHandler<TElement, undefined, TElement, TElement>): this;
on(events: string, data: any, handler: JQuery.TypeEventHandler<TElement, any, TElement, TElement>): this;
on(events: string, selector: string, handler: JQuery.TypeEventHandler<TElement, undefined, any, TElement>): this;
on(events: string, selector: string, data: any, handler: JQuery.TypeEventHandler<TElement, any, any, TElement>): this;
on(events: JQuery.TypeEventHandlers<TElement, undefined, TElement, TElement>): this;
on(events: JQuery.TypeEventHandlers<TElement, any, TElement, TElement>, data: any): this;
on(events: JQuery.TypeEventHandlers<TElement, undefined, any, TElement>, selector: string): this;
on(events: JQuery.TypeEventHandlers<TElement, any, any, TElement>, selector: string, data: any): this;
// Remove event handlers
off(): this;
off(events: string): this;
off(events: string, handler: JQuery.TypeEventHandler<TElement, any, any, TElement>): this;
off(events: string, selector: string): this;
off(events: string, selector: string, handler: JQuery.TypeEventHandler<TElement, any, any, TElement>): this;
off(events: JQuery.TypeEventHandlers<TElement, any, any, TElement>): this;
// Attach one-time event handlers
one(events: string, handler: JQuery.TypeEventHandler<TElement, undefined, TElement, TElement>): this;
one(events: string, data: any, handler: JQuery.TypeEventHandler<TElement, any, TElement, TElement>): this;
one(events: string, selector: string, handler: JQuery.TypeEventHandler<TElement, undefined, any, TElement>): this;
one(events: string, selector: string, data: any, handler: JQuery.TypeEventHandler<TElement, any, any, TElement>): this;
}declare namespace JQuery {
// Base event interface
interface EventBase {
type: string;
target: Element;
currentTarget: Element;
relatedTarget?: Element;
data?: any;
namespace?: string;
result?: any;
timeStamp: number;
// Methods
preventDefault(): void;
stopPropagation(): void;
stopImmediatePropagation(): void;
isDefaultPrevented(): boolean;
isPropagationStopped(): boolean;
isImmediatePropagationStopped(): boolean;
}
// Main event interface extending native Event
interface Event extends EventBase {
originalEvent?: globalThis.Event;
which?: number;
metaKey?: boolean;
pageX?: number;
pageY?: number;
clientX?: number;
clientY?: number;
offsetX?: number;
offsetY?: number;
}
// Specific event types
interface ClickEvent extends MouseEventBase {}
interface MouseEvent extends MouseEventBase {}
interface KeyboardEvent extends KeyEventBase {}
interface FocusEvent extends Event {}
interface ChangeEvent extends Event {}
interface SubmitEvent extends Event {}
interface ResizeEvent extends Event {}
interface ScrollEvent extends Event {}
}declare namespace JQuery {
type TypeEventHandler<
TTarget,
TData,
TCurrentTarget,
TDelegateTarget
> = (
this: TCurrentTarget,
event: TriggeredEvent<TCurrentTarget, TData, TTarget, TDelegateTarget>,
...extraParameters: any[]
) => void | false;
interface TriggeredEvent<TCurrentTarget = Element, TData = undefined, TTarget = Element, TDelegateTarget = Element>
extends Event {
currentTarget: TCurrentTarget;
data: TData;
delegateTarget: TDelegateTarget;
target: TTarget;
}
}// Click events
$('#button').on('click', function(event) {
console.log('Button clicked:', event.target);
event.preventDefault();
});
// Type-safe click handler
$('#button').on('click', (event: JQuery.ClickEvent) => {
console.log('Clicked at:', event.pageX, event.pageY);
if (event.shiftKey) {
console.log('Shift+click detected');
}
});
// Double click
$('#element').on('dblclick', function(event) {
console.log('Double clicked');
});
// Mouse enter/leave
$('.hover-target').on('mouseenter', function() {
$(this).addClass('hovered');
}).on('mouseleave', function() {
$(this).removeClass('hovered');
});
// Mouse move with coordinates
$('#canvas').on('mousemove', function(event: JQuery.MouseEvent) {
const x = event.offsetX!;
const y = event.offsetY!;
console.log(`Mouse at: ${x}, ${y}`);
});// Key down/up events
$('#input').on('keydown', function(event: JQuery.KeyboardEvent) {
console.log('Key pressed:', event.which);
// Handle specific keys
if (event.which === 13) { // Enter key
console.log('Enter pressed');
event.preventDefault();
}
if (event.ctrlKey && event.which === 83) { // Ctrl+S
console.log('Save shortcut');
event.preventDefault();
}
});
// Key press for character input
$('#input').on('keypress', function(event: JQuery.KeyboardEvent) {
const char = String.fromCharCode(event.which);
console.log('Character typed:', char);
});
// Input event for real-time text changes
$('#search').on('input', function() {
const query = $(this).val() as string;
console.log('Search query changed:', query);
});// Form submission
$('#myForm').on('submit', function(event: JQuery.SubmitEvent) {
event.preventDefault();
const formData = new FormData(this);
console.log('Form submitted with data:', Object.fromEntries(formData));
});
// Input change events
$('#select').on('change', function(event: JQuery.ChangeEvent) {
const selectedValue = $(this).val();
console.log('Selection changed:', selectedValue);
});
// Focus and blur events
$('input').on('focus', function() {
$(this).addClass('focused');
}).on('blur', function() {
$(this).removeClass('focused');
});
// Input validation on blur
$('#email').on('blur', function() {
const email = $(this).val() as string;
const isValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
$(this).toggleClass('valid', isValid).toggleClass('invalid', !isValid);
});// Event delegation for dynamic content
$(document).on('click', '.dynamic-button', function(event) {
console.log('Dynamic button clicked:', this);
});
// Delegated events with type safety
$('#container').on('click', '.item', function(event: JQuery.ClickEvent) {
const $item = $(this);
$item.toggleClass('selected');
});
// Multiple delegated events
$('#list').on({
'mouseenter': function() {
$(this).addClass('hover');
},
'mouseleave': function() {
$(this).removeClass('hover');
},
'click': function(event: JQuery.ClickEvent) {
event.stopPropagation();
$(this).trigger('item:selected');
}
}, '.list-item');
// Delegated form events
$('#form-container').on('change', 'input, select', function() {
const $form = $(this).closest('form');
$form.addClass('modified');
});// Multiple events with same handler
$('#element').on('mouseenter mouseleave', function(event) {
$(this).toggleClass('highlighted', event.type === 'mouseenter');
});
// Multiple events with different handlers
$('#element').on({
'click': function(event: JQuery.ClickEvent) {
console.log('Clicked');
},
'keydown': function(event: JQuery.KeyboardEvent) {
console.log('Key pressed:', event.which);
},
'focus blur': function(event: JQuery.FocusEvent) {
$(this).toggleClass('focused', event.type === 'focus');
}
});// Passing data to event handlers
$('#button').on('click', { userId: 123, action: 'save' }, function(event) {
console.log('User ID:', event.data.userId);
console.log('Action:', event.data.action);
});
// Data in delegated events
$('#container').on('click', '.item', { category: 'products' }, function(event) {
console.log('Category:', event.data.category);
console.log('Item clicked:', this);
});// One-time event handler
$('#element').one('click', function() {
console.log('This will only run once');
$(this).addClass('clicked-once');
});
// One-time with data
$('#element').one('custom:event', { message: 'Hello' }, function(event) {
console.log('One-time custom event:', event.data.message);
});
// One-time delegated event
$(document).one('click', '.special-button', function() {
console.log('Special button clicked once');
});// Trigger simple custom events
$('#element').trigger('custom:event');
$('#element').trigger('myEvent');
// Trigger with extra parameters
$('#element').trigger('custom:event', ['param1', 'param2']);
$('#element').trigger('custom:event', [{ data: 'value' }]);
// Create custom event objects
const customEvent = jQuery.Event('custom:event', {
bubbles: true,
cancelable: true,
customProperty: 'value'
});
$('#element').trigger(customEvent);
// Handle custom events
$('#element').on('custom:event', function(event, param1, param2) {
console.log('Custom event received:', param1, param2);
});// Namespaced events for organization
$('#element').on('click.myPlugin', function() {
console.log('Plugin click handler');
});
$('#element').on('click.myApp.validation', function() {
console.log('App validation click handler');
});
// Remove namespaced events
$('#element').off('click.myPlugin'); // Remove only myPlugin handlers
$('#element').off('.myApp'); // Remove all myApp handlers
$('#element').off('click.myApp'); // Remove myApp click handlers
// Multiple namespaces
$('#element').on('click.ns1.ns2', handler);
$('#element').off('.ns1'); // Removes handler (matches ns1)
$('#element').off('.ns2'); // Would also remove handler (matches ns2)$('#element').on('click', function(event: JQuery.ClickEvent) {
// Event type and timing
console.log('Event type:', event.type);
console.log('Timestamp:', event.timeStamp);
// Target information
console.log('Target element:', event.target);
console.log('Current target:', event.currentTarget);
console.log('Related target:', event.relatedTarget);
// Mouse coordinates
console.log('Page coordinates:', event.pageX, event.pageY);
console.log('Client coordinates:', event.clientX, event.clientY);
console.log('Offset coordinates:', event.offsetX, event.offsetY);
// Keyboard modifiers
console.log('Ctrl key:', event.ctrlKey);
console.log('Shift key:', event.shiftKey);
console.log('Alt key:', event.altKey);
console.log('Meta key:', event.metaKey);
// Key information
console.log('Which key:', event.which);
// Original native event
console.log('Original event:', event.originalEvent);
});// Event prevention and stopping
$('#form').on('submit', function(event: JQuery.SubmitEvent) {
// Prevent default browser behavior
event.preventDefault();
// Stop event bubbling
event.stopPropagation();
// Stop all other handlers on this element
event.stopImmediatePropagation();
// Check prevention status
if (event.isDefaultPrevented()) {
console.log('Default was prevented');
}
if (event.isPropagationStopped()) {
console.log('Propagation was stopped');
}
});
// Returning false does both preventDefault() and stopPropagation()
$('#link').on('click', function() {
return false; // Equivalent to event.preventDefault() + event.stopPropagation()
});// Store handler reference for later removal
const clickHandler = function(event: JQuery.ClickEvent) {
console.log('Click handled');
};
$('#element').on('click', clickHandler);
// Remove specific handler
$('#element').off('click', clickHandler);
// Remove all click handlers
$('#element').off('click');
// Remove all event handlers
$('#element').off();
// Remove delegated events
$(document).off('click', '.dynamic-element');// Window events
$(window).on('resize', function() {
console.log('Window resized:', $(window).width(), $(window).height());
});
$(window).on('scroll', function() {
const scrollTop = $(window).scrollTop()!;
console.log('Scroll position:', scrollTop);
});
$(window).on('load', function() {
console.log('Window fully loaded');
});
// Document ready (DOM ready)
$(document).ready(function() {
console.log('DOM ready');
});
// Shorthand for document ready
$(function() {
console.log('DOM ready (shorthand)');
});
// Document events
$(document).on('keydown', function(event: JQuery.KeyboardEvent) {
if (event.which === 27) { // Escape key
console.log('Escape pressed globally');
}
});// Define specific event handler types
type FormSubmitHandler = (event: JQuery.SubmitEvent) => void;
type ButtonClickHandler = (event: JQuery.ClickEvent) => void;
const handleFormSubmit: FormSubmitHandler = (event) => {
event.preventDefault();
console.log('Form submitted');
};
const handleButtonClick: ButtonClickHandler = (event) => {
console.log('Button clicked at:', event.pageX, event.pageY);
};
// Use typed handlers
$('#myForm').on('submit', handleFormSubmit);
$('#myButton').on('click', handleButtonClick);
// Custom event interfaces
interface CustomEventData {
userId: number;
action: string;
}
$('#element').on('custom:event', function(event, data: CustomEventData) {
console.log(`User ${data.userId} performed action: ${data.action}`);
});
// Trigger with proper typing
$('#element').trigger('custom:event', [{ userId: 123, action: 'save' } as CustomEventData]);// Use event delegation for dynamic content
$(document).on('click', '.button', handler); // Efficient for many buttons
// Instead of binding to each element
$('.button').on('click', handler); // Less efficient for dynamic content
// Debounce frequent events
let scrollTimeout: number;
$(window).on('scroll', function() {
clearTimeout(scrollTimeout);
scrollTimeout = window.setTimeout(() => {
console.log('Scroll ended');
}, 100);
});
// Throttle resize events
let resizeTimeout: number;
$(window).on('resize', function() {
if (!resizeTimeout) {
resizeTimeout = window.setTimeout(() => {
console.log('Resize handled');
resizeTimeout = 0;
}, 100);
}
});
// Remove unused event handlers
$('#temporary-element').off().remove();The event system provides comprehensive, type-safe handling for all browser events, custom events, and asynchronous operations. Combined with jQuery's delegation and namespacing features, it enables sophisticated interaction patterns while maintaining code clarity and performance.