Last active
October 31, 2018 02:32
-
-
Save mattijs/af286975efb4f8c4ec6a408baeb68551 to your computer and use it in GitHub Desktop.
DOM functions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// --- Selectors --------------------------------------------------------- | |
export function find(selector, el = document) { | |
return el.querySelector(selector); | |
} | |
export function findAll(selector, el = document) { | |
return el.querySelectorAll(selector); | |
} | |
// --- Element ----------------------------------------------------------- | |
export function element(type, ...args) { | |
const el = document.createElement(type); | |
for (let arg of args) { | |
if (arg instanceof Object && !Array.isArray(arg)) { | |
setProperties(el, arg); | |
} | |
else { | |
append(el, arg); | |
} | |
} | |
return el; | |
}; | |
export function append(element, ...children) { | |
if (children.length === 1 && Array.isArray(children[0])) { | |
return append(element, ...children[0]); | |
} | |
const fragment = document.createDocumentFragment(); | |
// Append each child to the fragment | |
for (let child of children) { | |
if (!(child instanceof Node)) { | |
child = document.createTextNode(String(child)); | |
} | |
fragment.appendChild(child); | |
} | |
// Append the fragment as a whole to the element | |
element.appendChild(fragment); | |
return element; | |
}; | |
export function clear(element) { | |
element.innerHTML = ''; | |
}; | |
/** | |
* Set the content of the element to the list of children. | |
* | |
* @param {Node} element | |
* @param {...Node|...String} children | |
* @returns {Node} | |
*/ | |
export function content(element, ...children) { | |
clear(element); | |
return append(element, ...children); | |
}; | |
/** | |
* List of node properties that should be considered attributes instead. | |
* @type {string[]} | |
*/ | |
const attributes = ['role']; | |
export function setProperties(element, properties) { | |
for (let [name, value] of Object.entries(properties)) { | |
if (!(name in element) && !attributes.includes(name)) { | |
const type = element.constructor.name; | |
throw new Error(`${name} is not a valid property of <${type}>`); | |
} | |
if (name === 'class') name = 'className'; | |
if (name === 'style') { | |
setStyles(el, value); | |
} | |
else { | |
element[name] = value; | |
} | |
} | |
return element; | |
}; | |
// --- Styling ------------------------------------------------------------ | |
export function setStyles(element, styles) { | |
const capitalize = value[0].toUpperCase() + value.slice(1); | |
for (let [name, value] of Object.entries(styles)) { | |
const segments = value.split('-').filter((v) => v.trim() !== ''); | |
const styleName = segments[0] + segments.slice(1).map(capitalize).join(''); | |
element.style[styleName] = value; | |
} | |
return element; | |
}; | |
export function addClass(element, ...classNames) { | |
element.classList.add(...classNames); | |
return element; | |
}; | |
export function removeClass(element, ...classNames) { | |
element.classList.remove(...classNames); | |
return element; | |
}; | |
export function toggleClass(element, className) { | |
element.classList.toggle(className); | |
return element; | |
}; | |
export function hasClass(element, className) { | |
return element.classList.contains(className); | |
}; | |
export function setClass(element, ...classNames) { | |
element.classList = [...classNames]; | |
return element; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment