Skip to content

Instantly share code, notes, and snippets.

@mattijs
Last active October 31, 2018 02:32
Show Gist options
  • Save mattijs/af286975efb4f8c4ec6a408baeb68551 to your computer and use it in GitHub Desktop.
Save mattijs/af286975efb4f8c4ec6a408baeb68551 to your computer and use it in GitHub Desktop.
DOM functions
// --- 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