💡 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