💡 Add custom dom wrapper (to be exported to a NPM lib)
This commit is contained in:
parent
cbce765d5f
commit
d61733827e
|
@ -0,0 +1,143 @@
|
|||
'use strict';
|
||||
|
||||
/**
|
||||
* dom.js
|
||||
* A module that helps working with HTML elements in the DOM
|
||||
*/
|
||||
|
||||
const boundaryRegex = /\s+/g;
|
||||
|
||||
/**
|
||||
* Add a wrapping of utility methods around a Node
|
||||
*
|
||||
* @param {Node} el Node to wrap
|
||||
* @return {Object} Utility-wrapped node
|
||||
*/
|
||||
const wrapNode = (el) => Object.freeze({
|
||||
node: el,
|
||||
|
||||
// shortcuts
|
||||
get: selector => wrapNode(el.querySelector(selector)),
|
||||
all: selector => wrapEls(el.querySelectorAll(selector)),
|
||||
|
||||
parent: () => wrapNode(el.parentNode),
|
||||
children: () => wrapEls(el.childNodes),
|
||||
|
||||
add: subEl => el.appendChild(unwrapNode(subEl)),
|
||||
remove: () => el.parentNode.removeChild(el),
|
||||
|
||||
getAttr: name => el.getAttribute(name),
|
||||
setAttr: (name, val) => el.setAttribute(name, val),
|
||||
|
||||
/**
|
||||
* Add event listeners for all given events
|
||||
*
|
||||
* @param {string} events Whitespace-separated list of events
|
||||
* @param {function} listener Listener to add
|
||||
* @return {null}
|
||||
*/
|
||||
on: (events, listener) => {
|
||||
events.trim().split(boundaryRegex).forEach(
|
||||
event => el.addEventListener(event, listener)
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove event listeners for all given events
|
||||
*
|
||||
* @param {strings} events Whitespace-separated list of events
|
||||
* @param {function} listener Listener to remove
|
||||
* @return {null}
|
||||
*/
|
||||
off: (events, listener) => {
|
||||
events.trim().split(boundaryRegex).forEach(
|
||||
event => el.removeEventListener(event, listener)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Remove a wrapping around a Node
|
||||
*
|
||||
* @param {Object|Node} el A node, wrapped or not
|
||||
* @return {Node} Unwrapped node
|
||||
*/
|
||||
const unwrapNode = el => el instanceof Node ? el : el.node;
|
||||
|
||||
/**
|
||||
* Override the methods of an Array so that it
|
||||
* can easily manipulate Nodes it contains
|
||||
*
|
||||
* @param {Array} list A list to be wrapped
|
||||
* @return {Array} Expanded list
|
||||
*/
|
||||
const expandList = (list) => Object.assign(list, {
|
||||
// shortcuts
|
||||
on: function (events, listener) {
|
||||
this.forEach(node => node.on(events, listener));
|
||||
},
|
||||
|
||||
off: function (events, listener) {
|
||||
this.forEach(node => node.off(events, listener));
|
||||
},
|
||||
|
||||
/**
|
||||
* Check whether this list includes given node
|
||||
*
|
||||
* @param {Node|Object} el Element to check
|
||||
* @return {bool} True if this list contains `el`
|
||||
*/
|
||||
includes: function (el) {
|
||||
const length = this.length;
|
||||
el = unwrapNode(el);
|
||||
|
||||
for (let i = 0; i < length; i += 1) {
|
||||
if (el === unwrapNode(this[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Filter nodes in the list, removing filtered out nodes
|
||||
*
|
||||
* @param {function} check A function that returns true to keep given el
|
||||
* @return {Array} New list of nodes after filtering
|
||||
*/
|
||||
filter: function (check) {
|
||||
const length = this.length, newList = [];
|
||||
|
||||
for (let i = 0; i < length; i += 1) {
|
||||
if (!check(this[i], i, this)) {
|
||||
this[i].remove();
|
||||
} else {
|
||||
newList.push(this[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return expandList(newList);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Turn a NodeList into a real Array of Nodes
|
||||
*
|
||||
* @param {NodeList} els List of nodes to wrap
|
||||
* @return {Array} An array of nodes
|
||||
*/
|
||||
const wrapList = (els) => {
|
||||
const result = [], length = els.length;
|
||||
|
||||
for (let i = 0; i < length; i += 1) {
|
||||
result[i] = wrapNode(els[i]);
|
||||
}
|
||||
|
||||
return expandList(result);
|
||||
};
|
||||
|
||||
export const create = (name) => wrapNode(document.createElement(name));
|
||||
export const html = wrapNode(document.documentElement);
|
||||
export const head = wrapNode(document.head);
|
||||
export const body = wrapNode(document.body);
|
Loading…
Reference in New Issue