UNPKG

almostnojs

Version:

A minimalist, dependency-free JavaScript framework for DOM manipulation, event handling, animations, state management, and HTTP requests.

195 lines (191 loc) 6.62 kB
/* AlmostNo.js v1.1.3 Events (CJS) */ var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/events.js var events_exports = {}; __export(events_exports, { bus: () => bus }); module.exports = __toCommonJS(events_exports); // src/core.js var globalScope = typeof window !== "undefined" ? window : global; if (!globalScope.__AnJS__) { class AnJS extends Array { /** * Initialize AnJS * * @param {string | HTMLElement | NodeList} query - CSS selector or element. */ constructor(query) { super(); if (!query) return; if (query instanceof HTMLElement || query.nodeType === 1) this.push(query); else if (query instanceof NodeList || Array.isArray(query)) this.push(...query); else if (typeof query === "string") this.push(...document.querySelectorAll(query)); } /** * Iterate through elements * * @param {Function} fn - Callback function. * @returns {AnJS} - Returns self for chaining. */ each(fn) { this.forEach(fn); return this; } /** * Get elements by index or return all * * @param {number} [index] - The index of the element to retrieve. * @returns {HTMLElement | Array} - The specific element or an array of elements. */ get(index) { return index === void 0 ? this : this.at(index); } /** * Clone the first selected element * * @param {boolean} [deep=true] - Clone children. * @returns {HTMLElement | null} - Cloned element. */ clone(deep = true) { return this[0] ? this[0].cloneNode(deep) : null; } } globalScope.__AnJS__ = AnJS; } var core_default = globalScope.__AnJS__; // src/events.js var eventStore = /* @__PURE__ */ new WeakMap(); Object.assign(core_default.prototype, { /** * Attach an event listener (direct or delegated) * * @param {string} event - Event type (e.g., 'click') * @param {string | Function} selector - Selector for delegation or event handler * @param {Function} [handler] - Event handler if delegation is used * @returns {AnJS} - Chainable instance */ on(event, selector, handler) { return typeof selector === "function" ? this.delegate(event, null, selector) : this.delegate(event, selector, handler); }, /** * Remove an event listener (direct or delegated) * * @param {string} event - Event type (e.g., 'click') * @param {string | Function} selector - Selector for delegation or event handler * @param {Function} [handler] - Event handler if delegation is used * @returns {AnJS} - Chainable instance */ off(event, selector, handler) { return typeof selector === "function" ? this.undelegate(event, null, selector) : this.undelegate(event, selector, handler); }, /** * Attach a delegated event listener using WeakMap for storage * * @param {string} event - Event type (e.g., 'click') * @param {string | null} selector - Selector to match (e.g., '.btn') or `null` for direct binding * @param {Function} handler - Event callback function * @returns {AnJS} - Chainable instance */ delegate(event, selector, handler) { return this.each((el) => { if (!eventStore.has(el)) eventStore.set(el, {}); const events = eventStore.get(el); if (!events[event]) events[event] = []; const delegateHandler = (e) => { const target = selector ? e.target.closest(selector) : el; if (target && el.contains(target)) handler.call(target, e); }; events[event].push({ selector, handler, delegateHandler }); el.addEventListener(event, delegateHandler); }); }, /** * Remove a delegated event listener using WeakMap * * @param {string} event - Event type (e.g., 'click') * @param {string | null} selector - Selector for delegation or `null` for direct binding * @param {Function} [handler] - Specific handler to remove (optional) * @returns {AnJS} - Chainable instance */ undelegate(event, selector, handler) { return this.each((el) => { if (!eventStore.has(el)) return; const events = eventStore.get(el); if (!events[event]) return; if (!handler) { events[event].forEach((item) => el.removeEventListener(event, item.delegateHandler)); delete events[event]; } else { events[event] = events[event].filter((item) => { if (item.selector === selector && item.handler === handler) { el.removeEventListener(event, item.delegateHandler); return false; } return true; }); if (events[event].length === 0) delete events[event]; } if (Object.keys(events).length === 0) eventStore.delete(el); }); }, /** * Trigger a custom event on elements * * @param {string} event - Event type to trigger (e.g., 'click') * @returns {AnJS} - Chainable instance */ trigger(event) { return this.each((el) => el.dispatchEvent(new Event(event, { bubbles: true }))); } }); var eventBus = {}; var bus = { /** * Emit a global event * * @param {string} event - The event name * @param {any} [data] - Optional data to send */ emit(event, data) { eventBus[event]?.forEach((handler) => handler(data)); }, /** * Listen for a global event * * @param {string} event - The event name * @param {Function} handler - The callback function */ listen(event, handler) { if (!eventBus[event]) eventBus[event] = []; eventBus[event].push(handler); }, /** * Remove a global event listener * * @param {string} event - The event name * @param {Function} handler - The callback function to remove */ forget(event, handler) { if (eventBus[event]) { eventBus[event] = eventBus[event].filter((h) => h !== handler); if (eventBus[event].length === 0) delete eventBus[event]; } } };