Extend / Modify InDom

InDom can be freely extended or modified — its core methods follow consistent patterns and naming, making it safe to build custom helpers or override behavior as needed.

Extend Example:
/**
 * Extend InDom with a custom helper: scrollTop getter / setter
 * Handles both Element and Document nodes, enforces integer input,
 * and uses requestAnimationFrame for smooth scrolling.
 */
InDom.prototype.scrollTop = function(y, smooth) {
	if (!y) {
		// document itself doesn't have scrollTop only its documentElement
		return (this.el() instanceof Document ? document.documentElement : this.el())
			.scrollTop;
	}
	if (!Number.isInteger(y)) { // accept only an integer for y to scroll
		throw new TypeError('Expected an integer to scrollTop, got ' + y);
	}
	requestAnimationFrame(() => {
		// if it is document it is better to scroll to window instead of its documentElement
		(this.el() instanceof Document ? window : this.el())
			.scrollTo({ top: y, behavior: smooth === true ? 'smooth' : 'instant' });
	});
};

// usage example 
$1(".example>div").onClick(() => $n(document).scrollTop(100, true));

Modify Example:
// Modify InDom with custom onClick method that throttles clicks and touchstart
InDom.prototype.onClick = function(fn, opts) {
    // If no function provided, delegate to standard click event
    if (!fn) {
        return this.on('click');
    }

    let canClick = true; // Throttle flag to prevent rapid repeated triggers

    // Attach handlers to both 'click' and 'touchstart' events
    return this.on(['click', 'touchstart'], (n, e) => {
        if (!canClick) {
            return; // Ignore rapid repeats during throttle period
        }
        canClick = false; // Disable further triggers
        setTimeout(() => canClick = true, 300); // Re-enable after 300ms
        fn(n, e); // Execute user-provided callback with InDom object and event
    }, opts);
};

// Bulk version for InDomArray - applies onClick to all InDom objects in the array
InDomArray.prototype.onClick = function(fn, opts) {
    const fnArr = new Array(this.length);
    for(let i = 0; i < this.length; i++) {
        // Apply onClick to each individual InDom object and store handler references
        fnArr[i] = this[i].onClick(fn, opts);
    }
    return fnArr; // Return array of handler references for cleanup
};

// Example usage:
const exampleDivs = $a(".example>div");

// Apply custom onClick behavior - logs HTML content and event details
const clickHandlers = exampleDivs.onClick((n, e) => {
    console.log(['.example>div onClick', 'html:', n.getHtml(), 'event:', e]);
});

// Example: Removing event handlers (cleanup)

// Method 1: Remove ALL click and touchstart listeners from exampleDivs
exampleDivs.off('click').off('touchstart'); 

// Method 2: Remove only the specific handlers we created
exampleDivs.off('click', clickHandlers).off('touchstart', clickHandlers);

Enhanced cleanup method — clarity and reusability for the above Modify Example
// Create custom removal methods for easier management

// Remove click/touchstart handlers from a single object
InDom.prototype.removeOnClick = function(fn) {
    this.off('click', fn);      // Remove click handler
    this.off('touchstart', fn); // Remove touchstart handler
};

// Remove click/touchstart handlers from multiple InDom objects in an array
InDomArray.prototype.removeOnClick = function(fnArr) {
    const hasFunctions = Array.isArray(fnArr);

    // Validate that the handler array matches the number of InDom objects
    if (hasFunctions && fnArr.length !== this.length) {
        throw new RangeError(`Expected ${this.length} handlers, got ${fnArr.length}`);
    }

    // Remove handlers from each InDom object individually
    for (let i = 0; i < this.length; i++) {
        this[i].removeOnClick(hasFunctions ? fnArr[i] : undefined);    
    }
};

// Usage examples for custom cleanup methods:

// Removes all 'click' and 'touchstart' events from exampleDivs
exampleDivs.removeOnClick();    

// Removes only the specific clickHandlers we created earlier
exampleDivs.removeOnClick(clickHandlers);
Modern DOM Power
for TypeScript, ESM & Plain JS
3.8KB JavaScript library that simplifies DOM manipulation
with a clean, chainable API for events, data, inputs harvesting, and more.
Automatic Cleanup,
Leak-Proof by Design
Events and state are cleared when elements leave the DOM,
even if removal happens outside InDom.
Cleaner Code,
Better Ergonomics
Get the InDom object directly in callbacks.
One element, one instance.
Works With Your Existing Stack
Use InDom on its own or alongside any library or framework,
its architecture ensures a seamless integration.