mirror of
https://codeberg.org/vlw/elevent.git
synced 2025-09-14 00:23:41 +02:00
Initial code commit
This commit is contained in:
parent
c602dbe39d
commit
6f254bf581
4 changed files with 147 additions and 0 deletions
16
.gitignore
vendored
Executable file
16
.gitignore
vendored
Executable file
|
@ -0,0 +1,16 @@
|
||||||
|
# Bootstrapping #
|
||||||
|
#################
|
||||||
|
vendor
|
||||||
|
.env.ini
|
||||||
|
|
||||||
|
# OS generated files #
|
||||||
|
######################
|
||||||
|
.DS_Store
|
||||||
|
.DS_Store?
|
||||||
|
._*
|
||||||
|
.Spotlight-V100
|
||||||
|
.Trashes
|
||||||
|
Icon?
|
||||||
|
ehthumbs.db
|
||||||
|
Thumbs.db
|
||||||
|
.directory
|
16
.npmignore
Normal file
16
.npmignore
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# Bootstrapping #
|
||||||
|
#################
|
||||||
|
vendor
|
||||||
|
.env.ini
|
||||||
|
|
||||||
|
# OS generated files #
|
||||||
|
######################
|
||||||
|
.DS_Store
|
||||||
|
.DS_Store?
|
||||||
|
._*
|
||||||
|
.Spotlight-V100
|
||||||
|
.Trashes
|
||||||
|
Icon?
|
||||||
|
ehthumbs.db
|
||||||
|
Thumbs.db
|
||||||
|
.directory
|
13
package.json
Normal file
13
package.json
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"name": "elevent",
|
||||||
|
"version": "1.1.2",
|
||||||
|
"main": "src/Elevent.mjs",
|
||||||
|
"type": "module",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"import": {
|
||||||
|
"default": "./src/Elevent.mjs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
102
src/Elevent.mjs
Normal file
102
src/Elevent.mjs
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
export class Elevent {
|
||||||
|
_type;
|
||||||
|
_callback;
|
||||||
|
_selector;
|
||||||
|
|
||||||
|
_boundElements = new WeakSet();
|
||||||
|
_controller = new AbortController();
|
||||||
|
_observer = new MutationObserver((mutations) => this.#mutationEvent(mutations));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new Elevent instance.
|
||||||
|
* @param {string|null} eventType
|
||||||
|
* @param {HTMLCollection|HTMLElement|string|null} target Strings will be treated as CSS selectors, null will create a template instance
|
||||||
|
* @param {function} callback
|
||||||
|
*/
|
||||||
|
constructor(eventType = null, target = null, callback) {
|
||||||
|
this._type = eventType;
|
||||||
|
this._callback = callback;
|
||||||
|
|
||||||
|
if (target) {
|
||||||
|
switch (target.constructor) {
|
||||||
|
case HTMLCollection:
|
||||||
|
this.#bindHTMLCollection(target);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case String:
|
||||||
|
this._selector = target;
|
||||||
|
this.#bindHTMLCollection(document.querySelectorAll(target));
|
||||||
|
|
||||||
|
// Automatically bind new DOM elements that match the provided CSS selector string
|
||||||
|
this._observer.observe(document.body, {
|
||||||
|
subtree: true,
|
||||||
|
childList: true
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (target instanceof HTMLElement) {
|
||||||
|
this.bind(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event handler for this._observer
|
||||||
|
* @param {array} mutations
|
||||||
|
*/
|
||||||
|
#mutationEvent(mutations) {
|
||||||
|
// Iterate over all MutationRecords
|
||||||
|
mutations.forEach(mutation => mutation.addedNodes.forEach(node => {
|
||||||
|
// Bind new element if its CSS selector matches and has not already been bound
|
||||||
|
if (node.matches(this._selector) && !this._boundElements.has(node)) {
|
||||||
|
this.bind(node);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bind all HTMLElements inside an HTMLCollection
|
||||||
|
* @param {HTMLCollection} collection
|
||||||
|
*/
|
||||||
|
#bindHTMLCollection(collection) {
|
||||||
|
[...collection].forEach(element => this.bind(element));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bind an element to this instance.
|
||||||
|
* @param {HTMLElement} target
|
||||||
|
*/
|
||||||
|
bind(target) {
|
||||||
|
/**
|
||||||
|
* Bind event listener of EventType on target element.
|
||||||
|
* The instance provided callback will only be executed if the target element is present in the bound elements Set.
|
||||||
|
*/
|
||||||
|
target.addEventListener(this._type, (event) => this._boundElements.has(target) && this._callback(event, this), {
|
||||||
|
signal: this._controller.signal
|
||||||
|
});
|
||||||
|
|
||||||
|
this._boundElements.add(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove all event listeners created from this instance.
|
||||||
|
* @param {HTMLElement} [target=null] An optional HTMLElement can be provided to soft-remove a specific element.
|
||||||
|
*/
|
||||||
|
remove(target = null) {
|
||||||
|
/**
|
||||||
|
* Soft-remove a single element from the bound elements Set.
|
||||||
|
* This will still trigger the event listener but the instance provided callback will not be executed.
|
||||||
|
*/
|
||||||
|
if (target) {
|
||||||
|
this._boundElements.delete(target);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._controller.abort();
|
||||||
|
this._observer.disconnect();
|
||||||
|
|
||||||
|
this._boundElements = new WeakSet();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue