Listenning to the native DOM events and other Modifiers
We quickly introduce helper to listening to the native DOM events. And library syntax/pattern so-called Modifier to incorporate not only this in UI templates declaratively.
Events and listenners
In JavaScript you can listen to the native DOM events of the given element by using element.addEventListener(type, listener, options)
. The library provides an alternative (on
) accepting the differen order of the arguments:
import { el, on } from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js";
const log= mark=> console.log.bind(console, mark);
const button= el("button", "Test click");
button.addEventListener("click", log("`addEventListener`"), { once: true });
on("click", log("`on`"), { once: true })(button);
document.body.append(
button
);
…this is actually one of the two differences. The another one is thaton
accepts only object as the options
(but it is still optional).
The other difference is that there is no off
function. You can remove listener declaratively using AbortSignal:
import { el, on } from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js";
const log= mark=> console.log.bind(console, mark);
const abort_controller= new AbortController();
const { signal }= abort_controller;
const button= el("button", "Test click");
button.addEventListener("click", log("`addEventListener`"), { signal });
on("click", log("`on`"), { signal })(button);
document.body.append(
button, " ", el("button", { textContent: "Off", onclick: ()=> abort_controller.abort() })
);
Modifiers
From practical point of view, Modifiers are just functions that accept any html element as their first parameter. You can see that the on(…)
fullfills this requirement.
You can use Modifiers as ≥3rd argument of el
function. This way is possible to extends you templates by additional (3rd party) functionalities. But for now mainly, you can add events listeners:
import { el, on } from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js";
const abort_controller= new AbortController();
const { signal }= abort_controller;
/** @type {ddeElementModifier<HTMLButtonElement>} */
const onclickOff= on("click", ()=> abort_controller.abort(), { signal });
/** @type {(ref?: HTMLOutputElement)=> HTMLOutputElement | null} */
const ref= (store=> ref=> ref ? (store= ref) : store)(null);
document.body.append(
el("button", "Test `on`",
on("click", console.log, { signal }),
on("click", update, { signal }),
on("mouseup", update, { signal })),
" ",
el("button", "Off", onclickOff),
el("output", { style: { display: "block", whiteSpace: "pre" } }, ref)
);
/** @param {MouseEvent} event @this {HTMLButtonElement} */
function update(event){
ref().append(
event.type,
"\n"
);
}
As the example shows, you can also provide types in JSDoc+TypeScript by using global type ddeElementModifier
. Also notice, you can use Modifiers to get element reference.
Life cycle events
Modifiers are called immediately when the element is created, event it is not connected to live DOM yet.