Skip to content

Instantly share code, notes, and snippets.

@rgchris
Last active November 19, 2021 03:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rgchris/1bac20f16b5ee710299d092bc8c4b947 to your computer and use it in GitHub Desktop.
Save rgchris/1bac20f16b5ee710299d092bc8c4b947 to your computer and use it in GitHub Desktop.
DOM Builder
const Bd = function (name, attrs, ...kids) {
const spaces = {
xhtml: 'http://www.w3.org/1999/xhtml',
svg: 'http://www.w3.org/2000/svg'
}
const fullname = name.split(':')
name = fullname.pop()
const ns = spaces[
fullname.pop() || 'xhtml'
]
const node = document.createElementNS(ns, name)
if (attrs) {
for (const attr in attrs) {
if (
attrs.hasOwnProperty(attr)
&&
attrs[attr] !== undefined
) {
if (typeof attrs[attr] === 'function') {
node.addEventListener(
attr, attrs[attr]
)
}
else if (Array.isArray(attrs[attr])) {
typeof attrs[attr][0] === 'function'
? node.addEventListener(
attr, ...attrs[attr]
)
: Error('Cannot set Array as attribute')
}
else {
node.setAttribute(
attr, attrs[attr]
)
}
}
}
}
for (const kid of kids) {
if (Array.isArray(kid)) {
if (kid[0] === '.partial') {
const container = document.createElementNS(
ns,
ns === spaces['svg'] ? 'g' : 'div'
)
container.innerHTML = kid[1]
while (container.firstChild) {
node.appendChild(
container.removeChild(
container.firstChild
)
)
}
}
else {
node.appendChild(
Bd(...kid)
)
}
}
else if (typeof kid === 'string') {
node.appendChild(
document.createTextNode(kid)
)
}
}
return new.target
? (this.value = node, this)
: node
}
document.body.appendChild(
Bd(
'div', { click: function() {alert('hi')} },
[ 'p',, 'Some Text' ],
[
'svg:svg',
{ xmlns: 'http://www.w3.org/2000/svg', width: 200, height: 200, viewBox: '0,0 200,200' },
[ 'svg:path', {d: 'M50,50 L150,150 L50,150'}, ]
]
)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment