DOM element helper
A tiny function to create HTML elements, similar to transpiled JSX
TLDR;
Use this h function
const h=(e,a,c=[])=>(e=document.createElement(e),a&&Object.assign(e,a),e.append(...c),e)
Usage
The h function is able to do things like the following.
Create an empty div:
const element = h('div')
Create a div with a class and an attribute:
const myDiv = h('div', {class: 'foo', id: 'bar'})
Create a “save” button:
const myDiv = h('button', {}, ['Save'])
Create a list:
const list = h('ul', null, [
h('li', null, 'Item 1'),
h('li', null, 'Item 2')
])
Motivation
My main use case is to have a helper function to create DOM elements in Web Components. It should be kind of compatible with JSX signature, but it does not implement JSX specifications. For example event handlers should be managed by Web Component itself, so props can be only DOM attributes (i.e. only strings or numbers).
First implementation
This is a first implementation, written in TypeScript and in a comprehensive way.
It does not support SVG elements, there is another implementation down below that is aware of namespaceURI argument for createElementNS.
function h(
tagName: keyof HTMLElementTagNameMap,
attributes: Record<string, string> | null = null,
children: Array<number | string | HTMLElement> = []
): HTMLElementTagNameMap[typeof tagName] {
// Create the element with the given tag name.
const element = document.createElement(tagName)
// Set attributes on the element.
if (attributes)
for (const [key, value] of Object.entries(attributes))
element.setAttribute(key, value)
// Create and append children.
for (const child of children)
element.appendChild(
(typeof child === 'string' || typeof child === 'number')
? document.createTextNode(child)
: child
)
// Return the created element.
return element
}
Shorter implementation
This is an (almost) equivalent implementation, using few tricks to make it shorter. It makes it perfect to copy and paste in a stand alone Web Component and use it to generate DOM elements.
Notice that the comments are the same as the previous implementation, so you can spot the analogy between the two.