Files
jsl/dom.js

109 lines
3.2 KiB
JavaScript
Raw Normal View History

2025-09-20 22:59:18 +02:00
/*
* This file is part of NoccyLabs JavaScript Standard Library (JSL)
* Copyright (c) 2025, NoccyLabs. Licensed under GNU GPL v2 or later
*
*
*/
/**
* A helper class to create (and manipulate) elements in the DOM.
*
*/
class DomHelper {
/**
* Create a new element without all the fuzz.
*
* @param {string} tag The name of the HTML tag
* @param {object} attr Map of attributes to apply to the element
* @param {array|Element|string} children Children or single child/text to apply
* @returns Element
*/
2025-09-21 01:26:06 +02:00
create(tag, attr = {}, children = []) {
2025-09-20 22:59:18 +02:00
//console.debug(`create: ${tag}`, attr, children);
let el = document.createElement(tag);
this.apply(el, attr);
this.append(el, children);
return el;
};
/**
* Apply attributes from an object to an element
*
* @param {Element} tag The element to modify
* @param {object} attr Key-value pairs of attributes to apply, or if null remove
*/
apply(tag, attr) {
Object.keys(attr).forEach(key => {
if (key.match(/^on:/)) {
const ev = key.substring(3);
tag.addEventListener(ev, attr[key]);
return;
}
if (attr[key] === null) {
tag.removeAttribute(key);
} else {
tag.setAttribute(key, attr[key]);
}
});
}
/**
* Append one or more children or text nodes to an element.
*
* @param {Element} tag The element to modify
* @param {array|Element|string} children List of elements or single element to append to the element
* @returns
*/
append(tag, children) {
// Handle null, to make it easy to skip items with conditionals
if (children === null) return;
2025-09-20 22:59:18 +02:00
//console.debug(`append: ${tag.nodeName}`, children);
if (typeof children == 'object' && children instanceof Element) {
//console.debug(`-> appended element`);
tag.appendChild(children);
return;
}
if (typeof children == 'string') {
//console.debug(`-> appended string`);
let n = document.createTextNode(children);
tag.appendChild(n);
return;
}
if (Array.isArray(children)) {
children.forEach(child => {
this.append(tag, child);
});
//console.debug(`-> appended nested`);
}
}
/**
* Apply templated values to a string
*
* @param {string} str The string to perform interpolation on
* @param {object} tpl A string of key-value pair to replace between percent signs
* @returns string
*/
interpolate(str, tpl) {
Object.keys(tpl).forEach(key => {
str = str.replace(`%${key}%`, tpl[key]);
});
return str;
}
};
// The DOM helper
const dom = new DomHelper();
// Proxy for creating any supported HTML element via el.TAG
const el = new Proxy(dom, {
get(target,name) {
return name in target
? target[name]
2025-09-21 01:26:06 +02:00
: (attr = {}, children = []) => target.create(name, attr, children);
2025-09-20 22:59:18 +02:00
}
});
export { dom, el };