Skip to content

Instantly share code, notes, and snippets.

@jon49
Last active August 23, 2025 08:10
Show Gist options
  • Select an option

  • Save jon49/28f84694272e39e2b642efa69b507c6e to your computer and use it in GitHub Desktop.

Select an option

Save jon49/28f84694272e39e2b642efa69b507c6e to your computer and use it in GitHub Desktop.
Web component adder
class Adder extends HTMLElement {
constructor() {
super()
this.elements = getXElements(this)
this.addEventListener('input', this)
}
handleEvent(event) {
handleEvent(this, event)
}
add() {
let num1 = +this.elements.num1.value
let num2 = +this.elements.num2.value
this.elements.target.textContent = `${num1} + ${num2} = ${num1 + num2}`
}
}
customElements.define('x-adder', Adder)
function getXElements(fragment) {
let o = {}
for (let el of fragment.querySelectorAll(`[x]`)) {
o[el.getAttribute('x') || ''] = el
el.removeAttribute('x')
}
return o
}
function handleEvent(context, event) {
event.stopPropagation()
event.preventDefault()
let target = event.target
if (target instanceof HTMLElement) {
// @ts-ignore
let action = target.dataset.action || target.closest('[data-action]')?.dataset?.action
if (action) {
if (context[action] instanceof Function) {
requestAnimationFrame(() => {
context[action](event)
})
} else {
console.error(`Action ${action} not implemented.`)
}
} else if (context[event.type] instanceof Function) {
context[event.type](event)
}
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Adder</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h1>Add numbers!</h1>
<x-adder>
<input x=num1 data-action=add type="number">
<input x=num2 data-action=add type="number">
<p x=target></p>
</x-adder>
<script type=module src="./adder.js"></script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment