I guess most people did not understand what I was trying to achieve with this code snippet; I'm trying, with the less amount of code possible, to create HTML elements dynamically; no React alternatives or frameworks. Anyways, here's my second iteration on the code snippet.<p><pre><code> const tagNames = [
'a', 'abbr', 'address', 'area', 'article', 'aside', 'audio', 'b', 'base',
'bdi', 'bdo', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption',
'cite', 'code', 'col', 'colgroup', 'data', 'datalist', 'dd', 'del',
'details', 'dfn', 'dialog', 'div', 'dl', 'dt', 'em', 'embed', 'fieldset',
'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5',
'h6', 'head', 'header', 'hr', 'html', 'i', 'iframe', 'img', 'input', 'ins',
'kbd', 'label', 'legend', 'li', 'link', 'main', 'map', 'mark', 'meta',
'meter', 'nav', 'noscript', 'object', 'ol', 'optgroup', 'option', 'output',
'p', 'param', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's',
'samp', 'script', 'section', 'select', 'small', 'source', 'span', 'strong',
'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template',
'textarea', 'tfoot', 'th', 'thead', 'time', 'title', 'tr', 'track', 'u',
'ul', 'var', 'video', 'wbr'
]
const assignDeep = (elm, props) => Object.entries(props).forEach(([key, value]) =>
typeof value === 'object' ? assignDeep(elm[key], value) : Object.assign(elm, {[key]: value}))
tagNames.forEach(tag => window[tag] = function() {
const [arg1, arg2] = arguments
const props = arg2 ? typeof arg1 == 'object' ? arg1 : null : null
let children = props ? arg2 : arg1
if (!Array.isArray(children)) children = [children]
const elm = document.createElement(tag)
props && assignDeep(elm, props)
elm.append(...children.map(c => typeof c == 'string' ? document.createTextNode(c) : c))
return elm
})
</code></pre>
Now I can use it like this:<p><pre><code> const blogPost = div({className: 'blog-post'}, [
h1('My blog post'),
div({className: 'body'}, p('My first blog post')),
div({className: 'footer'}, [
span(['Author: ', a({href: '#'}, 'atum47')]),
span(['Date: ', new Date().toLocaleString()])
])
])
document.body.append(blogPost)
</code></pre>
Basically I'm creating a function for each tagName, so instead of calling <i>document.createElement('p')</i> I can just call <i>p()</i>. Other than that I do some argument manipulation to see if the function is being called with props or children