Skip to content

Instantly share code, notes, and snippets.

@nexpr
Created June 16, 2022 14:04
Show Gist options
  • Save nexpr/3ceeeee380b07293d8276d6fd2607856 to your computer and use it in GitHub Desktop.
Save nexpr/3ceeeee380b07293d8276d6fd2607856 to your computer and use it in GitHub Desktop.
create dom element module
import dom from "./dom.js"
// 1
const div = dom.div({ className: "foo" }, [
dom.input(),
dom.input({ type: "checkbox" })
])
document.body.append(div)
// 2
dom.resolveProps = (elem, props) => {
for (const [key, value] of Object.entries(props)) {
if (key === "class") {
if (Array.isArray(value)) {
elem.className = value.filter(Boolean).join(" ")
} else if (value && typeof value === "object") {
elem.className = Object.entries(value).filter(([k, v]) => v).map(([k]) => k).join(" ")
} else {
elem.className = value
}
} else if (key.startsWith("on") && typeof value === "function") {
elem.addEventListener(key.slice(2), value)
} else {
elem[key] = value
}
}
}
const buttons = dom.div({ class: "buttons" }, [
dom.button(
{
class: ["foo", "bar"],
onclick: () => {
alert("clicked1")
},
},
"Button1"
),
dom.button(
{
class: { baz: true, qux: false },
onclick: () => {
alert("clicked2")
},
},
"Button2"
)
])
document.body.append(buttons)
const tags = [
"html",
"head",
"title",
"base",
"link",
"meta",
"style",
"body",
"article",
"section",
"nav",
"aside",
"h1",
"h2",
"h3",
"h4",
"h5",
"h6",
"hgroup",
"header",
"footer",
"address",
"p",
"hr",
"pre",
"blockquote",
"ol",
"ul",
"menu",
"li",
"dl",
"dt",
"dd",
"figure",
"figcaption",
"main",
"div",
"a",
"em",
"strong",
"small",
"s",
"cite",
"q",
"dfn",
"abbr",
"ruby",
"rt",
"rp",
"data",
"time",
"code",
"var",
"samp",
"kbd",
"sub",
"sup",
"i",
"b",
"u",
"mark",
"bdi",
"bdo",
"span",
"br",
"wbr",
"ins",
"del",
"picture",
"source",
"img",
"iframe",
"embed",
"object",
"video",
"audio",
"track",
"map",
"area",
"table",
"caption",
"colgroup",
"col",
"tbody",
"thead",
"tfoot",
"tr",
"td",
"th",
"form",
"label",
"input",
"button",
"select",
"datalist",
"optgroup",
"option",
"textarea",
"output",
"progress",
"meter",
"fieldset",
"legend",
"details",
"summary",
"dialog",
"script",
"noscript",
"template",
"slot",
"canvas",
]
const dom = {}
dom.resolveProps = (elem, props) => {
Object.assign(elem, props)
}
const create = (tag) => (props = {}, children = []) => {
const elem = document.createElement(tag)
dom.resolveProps(elem, props)
elem.append(...(Array.isArray(children) ? children : [children]))
return elem
}
for (const tag of tags) {
dom[tag] = create(tag)
}
export default dom
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment