Core event handling and lifecycle management for processing new content and managing user interactions in htmx applications.
Processes new content to enable htmx behavior on dynamically added elements.
/**
* Processes new content, enabling htmx behavior on elements
* @param elt - Element or CSS selector to process
*/
function process(elt: Element | string): void;Usage Example:
// Process dynamically added content
const newDiv = document.createElement('div');
newDiv.innerHTML = '<button hx-get="/api/data">Click me</button>';
document.body.appendChild(newDiv);
// Enable htmx behavior on the new content
htmx.process(newDiv);
// Or process by selector
htmx.process('#dynamic-content');Registers callbacks to run when new content is loaded and processed by htmx.
/**
* Adds a callback for the htmx:load event to process new content
* @param callback - Function to call on newly loaded content
* @returns EventListener that was registered
*/
function onLoad(callback: (elt: Node) => void): EventListener;Usage Example:
// Register callback for all newly loaded content
htmx.onLoad(function(content) {
console.log('New content loaded:', content);
// Initialize custom components in the new content
const widgets = content.querySelectorAll('.my-widget');
widgets.forEach(widget => {
// Initialize widget functionality
initializeWidget(widget);
});
});
// The callback fires for:
// - Initial page load
// - AJAX response content
// - Content added via hx-swap-oobAdd and remove event listeners with htmx-aware handling.
/**
* Adds an event listener to an element with htmx-aware handling
* Supports multiple overload patterns for flexible usage
*/
function on(target: EventTarget | string, event: string, listener: EventListener, options?: any): EventListener;
function on(event: string, listener: EventListener): EventListener; // Global listener
function on(target: EventTarget | string, event: string, listener: EventListener, options?: boolean): EventListener;
/**
* Removes an event listener from an element
*/
function off(target: EventTarget | string, event: string, listener?: EventListener): EventListener;
function off(event: string, listener: EventListener): EventListener; // Global listener removalUsage Examples:
// Add event listener to specific element
const button = document.getElementById('my-button');
htmx.on(button, 'click', function(e) {
console.log('Button clicked');
});
// Add global event listener using selector
htmx.on('click', function(e) {
if (e.target.matches('.my-class')) {
console.log('Element with .my-class clicked');
}
});
// Add event listener by selector string
htmx.on('#my-form', 'submit', function(e) {
console.log('Form submitted');
});
// Add with options
htmx.on(document, 'keydown', handleKeydown, { passive: true });
// Remove event listener
const handler = function(e) { console.log('clicked'); };
htmx.on('#button', 'click', handler);
htmx.off('#button', 'click', handler);
// Remove global listener
htmx.off('click', globalHandler);Triggers custom events on elements, useful for programmatic event firing and inter-component communication.
/**
* Triggers a given event on an element
* @param elt - Target element or CSS selector
* @param eventName - Name of the event to trigger
* @param detail - Optional event detail data
* @returns boolean indicating if event was not cancelled
*/
function trigger(elt: EventTarget | string, eventName: string, detail?: any): boolean;Usage Examples:
// Trigger simple event
htmx.trigger('#my-element', 'customEvent');
// Trigger event with data
htmx.trigger(document.body, 'dataUpdated', {
timestamp: Date.now(),
source: 'user-action'
});
// Trigger htmx built-in events
htmx.trigger('#form', 'htmx:validate');
htmx.trigger('.loading-indicator', 'htmx:abort');
// Use return value to check if event was cancelled
const wasProcessed = htmx.trigger('#component', 'beforeAction');
if (wasProcessed) {
// Event was not cancelled, proceed
performAction();
}Understanding htmx's event system is crucial for effective event processing:
htmx:configRequesthtmx:beforeRequesthtmx:afterRequesthtmx:sendErrorhtmx:responseErrorhtmx:beforeSwaphtmx:afterSwaphtmx:beforeSettlehtmx:afterSettlehtmx:loadhtmx:aborthtmx:confirmhtmx:prompthtmx:pushedIntoHistoryhtmx:replacedInHistoryEvent Handling Example:
// Listen for request start
htmx.on('htmx:beforeRequest', function(evt) {
console.log('Starting request to:', evt.detail.requestConfig.path);
// Show loading indicator
showLoading();
});
// Listen for request completion
htmx.on('htmx:afterRequest', function(evt) {
console.log('Request completed');
hideLoading();
// Check for errors
if (evt.detail.failed) {
console.error('Request failed');
showError('Request failed, please try again');
}
});
// Listen for new content
htmx.on('htmx:load', function(evt) {
// Initialize components in new content
initializeComponents(evt.target);
});
// Override confirmation
htmx.on('htmx:confirm', function(evt) {
// Use custom confirmation dialog
evt.preventDefault();
showCustomConfirm(evt.detail.question).then(confirmed => {
if (confirmed) {
evt.detail.issueRequest();
}
});
});Event processing integrates well with frontend frameworks:
// React integration
useEffect(() => {
const cleanup = htmx.onLoad((content) => {
// Process React components in htmx content
const reactMounts = content.querySelectorAll('[data-react-component]');
reactMounts.forEach(mount => {
const componentName = mount.dataset.reactComponent;
const props = JSON.parse(mount.dataset.reactProps || '{}');
ReactDOM.render(React.createElement(components[componentName], props), mount);
});
});
return () => htmx.off('htmx:load', cleanup);
}, []);
// Vue integration
htmx.onLoad((content) => {
const vueApps = content.querySelectorAll('[data-vue-app]');
vueApps.forEach(el => {
const app = createApp({
// Vue component definition
});
app.mount(el);
});
});