UNPKG

domkitjs

Version:

A dom manipulation package for all your needs!

446 lines 13.7 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import waitForDomContentLoaded from "./utils/waitForDomContentLoaded"; /** * Shortcut for document.querySelector that works exactly like it but returns `false` if no element is found. * Automatically waits for the DOM to be ready. * * @param {string} selector - The CSS selector to match the element. * @returns {Promise<HTMLElement | false>} The found HTML element or `false` if no element is found. * * @example * // Querying selector and waiting for the DOM to be ready * const elem = await qry('#my-element'); * if (elem) { * console.log('Element found:', elem); * } else { * console.log('Element not found'); * } */ export function qry(selector) { return __awaiter(this, void 0, void 0, function* () { yield waitForDomContentLoaded(); const foundElem = document.querySelector(selector); return foundElem ? foundElem : false; }); } /** * Shortcut for document.querySelectorAll that works exactly like it but returns `false` if no elements are found. * Automatically waits for the DOM to be ready. * * @param {string} selector - The CSS selector to match the elements. * @returns {Promise<NodeListOf<HTMLElement> | false>} A NodeList of found HTML elements or `false` if no elements are found. * * @example * // Querying selector and waiting for the DOM to be ready * const elems = await qryAll('.list-item'); * if (elems) { * elems.forEach(elem => console.log('Element found:', elem)); * } else { * console.log('No elements found'); * } */ export function qryAll(selector) { return __awaiter(this, void 0, void 0, function* () { yield waitForDomContentLoaded(); const foundElems = document.querySelectorAll(selector); return foundElems.length > 0 ? foundElems : false; }); } /** * Shortcut for document.getElementById that works exactly like it but returns `false` if no element is found. * Automatically waits for the DOM to be ready. * * @param {string} id - The id of the element to find. * @returns {Promise<HTMLElement | false>} The found HTML element or `false` if no element is found. * * @example * // Querying ID and waiting for the DOM to be ready * const elem = await id('header'); * if (elem) { * console.log('Element found:', elem); * } else { * console.log('Element not found'); * } */ export function qryById(id) { return __awaiter(this, void 0, void 0, function* () { yield waitForDomContentLoaded(); const foundElem = document.getElementById(id); return foundElem ? foundElem : false; }); } /** * Extends HTMLElement prototype to support 'on' method. * * @param {string} event - The event type to listen for. * @param {EventListenerOrEventListenerObject} callback - The callback function to execute when the event is triggered. * @returns {HTMLElement} The element itself to allow method chaining. */ /** * Extends HTMLElement prototype to support 'on' method. * * @param {string} event - The event type to listen for. * @param {EventListenerOrEventListenerObject} callback - The callback function to execute when the event is triggered. * @returns {HTMLElement} The element itself to allow method chaining. */ HTMLElement.prototype.on = function (event, callback) { this.addEventListener(event, callback); return this; }; /** * Extends NodeList prototype to support 'on' method. * * @param {string} event - The event type to listen for. * @param {EventListenerOrEventListenerObject} callback - The callback function to execute when the event is triggered. * @returns {NodeListOf<HTMLElement>} The NodeList itself to allow method chaining. */ NodeList.prototype.on = function (event, callback) { this.forEach(element => element.addEventListener(event, callback)); return this; }; /** * Checks if an element has a specific class. * * @param {string} className - The class name to check for. * @returns {boolean} `true` if the class is present, otherwise `false`. * * @example * const elem = qry('.my-element'); * if (elem && elem.hasClass('active')) { * console.log('Element has the class active'); * } */ HTMLElement.prototype.hasClass = function (className) { return this.classList.contains(className); }; /** * Adds a class to an element. * * @param {string} className - The class name to add. * @returns {HTMLElement} The element itself to allow method chaining. * * @example * const elem = qry('.my-element'); * if (elem) { * elem.addClass('active'); * } */ HTMLElement.prototype.addClass = function (className) { this.classList.add(className); return this; }; /** * Removes a class from an element. * * @param {string} className - The class name to remove. * @returns {HTMLElement} The element itself to allow method chaining. * * @example * const elem = qry('.my-element'); * if (elem) { * elem.removeClass('active'); * } */ /** * Removes a class from an element. * * @param {string} className - The class name to remove. * @returns {HTMLElement} The element itself to allow method chaining. */ HTMLElement.prototype.removeClass = function (className) { this.classList.remove(className); return this; }; /** * Toggles a class on an element. * * @param {string} className - The class name to toggle. * @param {boolean} [force] - If `true`, the class will be added; if `false`, it will be removed. * @returns {HTMLElement} The element itself to allow method chaining. * * @example * const elem = qry('.my-element'); * if (elem) { * elem.toggleClass('active'); * } */ HTMLElement.prototype.toggleClass = function (className, force) { this.classList.toggle(className, force); return this; }; /** * Sets an attribute on an element. * * @param {string} name - The attribute name. * @param {string} value - The attribute value. * @returns {HTMLElement} The element itself to allow method chaining. * * @example * const elem = qry('.my-element'); * if (elem) { * elem.setAttribute('data-role', 'admin'); * } */ HTMLElement.prototype.setAttribute = function (name, value) { this.setAttribute(name, value); return this; }; /** * Gets an attribute from an element. * * @param {string} name - The attribute name. * @returns {string | null} The attribute value, or `null` if the attribute does not exist. * * @example * const elem = qry('.my-element'); * if (elem) { * console.log(elem.getAttribute('data-role')); // Outputs the value of the 'data-role' attribute * } */ HTMLElement.prototype.getAttribute = function (name) { return this.getAttribute(name); }; /** * Removes an attribute from an element. * * @param {string} name - The attribute name. * @returns {HTMLElement} The element itself to allow method chaining. * * @example * const elem = qry('.my-element'); * if (elem) { * elem.removeAttribute('data-role'); * } */ HTMLElement.prototype.removeAttribute = function (name) { this.removeAttribute(name); return this; }; /** * Appends content to an element. * * @param {Node | string} content - The content to append. * @returns {HTMLElement} The element itself to allow method chaining. * * @example * const elem = qry('.my-element'); * if (elem) { * elem.append('<span>New Content</span>'); * } */ HTMLElement.prototype.append = function (content) { if (typeof content === 'string') { this.insertAdjacentHTML('beforeend', content); } else { this.appendChild(content); } return this; }; /** * Prepends content to an element. * * @param {Node | string} content - The content to prepend. * @returns {HTMLElement} The element itself to allow method chaining. * * @example * const elem = qry('.my-element'); * if (elem) { * elem.prepend('<span>New Content</span>'); * } */ HTMLElement.prototype.prepend = function (content) { if (typeof content === 'string') { this.insertAdjacentHTML('afterbegin', content); } else { this.prepend(content); } return this; }; /** * Removes all child elements from an element. * * @returns {HTMLElement} The element itself to allow method chaining. * * @example * const elem = qry('.my-element'); * if (elem) { * elem.empty(); * } */ HTMLElement.prototype.empty = function () { while (this.firstChild) { this.removeChild(this.firstChild); } return this; }; /** * Fades in an element with animation. * * @param {number} duration - The duration of the fade-in effect in milliseconds. * @returns {HTMLElement} The element itself to allow method chaining. * * @example * const elem = qry('.my-element'); * if (elem) { * elem.fadeIn(500); * } */ HTMLElement.prototype.fadeIn = function (duration) { this.style.opacity = '0'; this.style.display = ''; this.style.transition = `opacity ${duration}ms`; requestAnimationFrame(() => { this.style.opacity = '1'; }); return this; }; /** * Fades out an element with animation. * * @param {number} duration - The duration of the fade-out effect in milliseconds. * @returns {HTMLElement} The element itself to allow method chaining. * * @example * const elem = qry('.my-element'); * if (elem) { * elem.fadeOut(500); * } */ HTMLElement.prototype.fadeOut = function (duration) { this.style.opacity = '1'; this.style.transition = `opacity ${duration}ms`; requestAnimationFrame(() => { this.style.opacity = '0'; setTimeout(() => { this.style.display = 'none'; }, duration); }); return this; }; /** * Scrolls an element to the top. * * @param {number} [duration=300] - The duration of the scroll effect in milliseconds. * @returns {HTMLElement} The element itself to allow method chaining. * * @example * const elem = qry('.my-element'); * if (elem) { * elem.scrollToTop(); * } */ HTMLElement.prototype.scrollToTop = function (duration = 300) { const start = this.scrollTop; const startTime = performance.now(); const scroll = (timestamp) => { const progress = Math.min((timestamp - startTime) / duration, 1); this.scrollTop = start * (1 - progress); if (progress < 1) { requestAnimationFrame(scroll); } }; requestAnimationFrame(scroll); return this; }; /** * Scrolls an element to the bottom. * * @param {number} [duration=300] - The duration of the scroll effect in milliseconds. * @returns {HTMLElement} The element itself to allow method chaining. * * @example * const elem = qry('.my-element'); * if (elem) { * elem.scrollToBottom(); * } */ HTMLElement.prototype.scrollToBottom = function (duration = 300) { const start = this.scrollTop; const end = this.scrollHeight - this.clientHeight; const startTime = performance.now(); const scroll = (timestamp) => { const progress = Math.min((timestamp - startTime) / duration, 1); this.scrollTop = start + (end - start) * progress; if (progress < 1) { requestAnimationFrame(scroll.bind(this)); } }; requestAnimationFrame(scroll.bind(this)); return this; }; /** * Clones an element, with or without children. * * @param {boolean} [deep=false] - Whether to clone the element's children. * @returns {HTMLElement} The cloned element. * * @example * const elem = qry('.my-element'); * if (elem) { * const clone = elem.clone(true); // deep clone * document.body.append(clone); * } */ HTMLElement.prototype.clone = function (deep = false) { return this.cloneNode(deep); }; /** * Finds the closest ancestor element that matches the specified selector. * * @param {string} selector - The CSS selector to match the ancestor element. * @returns {HTMLElement | null} The closest ancestor element that matches the selector, or `null` if none is found. * * @example * const elem = qry('.my-element'); * if (elem) { * const ancestor = elem.closestAncestor('.parent-class'); * console.log(ancestor); * } */ HTMLElement.prototype.closestAncestor = function (selector) { return this.closest(selector); }; /** * Finds child elements that match the specified selector. * * @param {string} selector - The CSS selector to match the child elements. * @returns {NodeListOf<HTMLElement>} A NodeList of found child elements. * * @example * const elem = qry('#parent'); * if (elem) { * const children = elem.findChildren('.child'); * children.forEach(child => console.log(child)); * } */ HTMLElement.prototype.findChildren = function (selector) { return this.querySelectorAll(selector); }; /** * Removes all child elements from an element. * * @returns {HTMLElement} The element itself to allow method chaining. * * @example * const elem = qry('#parent'); * if (elem) { * elem.removeChildren(); * } */ HTMLElement.prototype.removeChildren = function () { while (this.firstChild) { this.removeChild(this.firstChild); } return this; }; //# sourceMappingURL=domkit.js.map