mirror of
https://github.com/jaandrle/deka-dom-el
synced 2025-07-01 04:12:14 +02:00
v0.7.1 (dispatchEvent, docs)
This commit is contained in:
14
docs_src/components/examples/events/compareDispatch.js
Normal file
14
docs_src/components/examples/events/compareDispatch.js
Normal file
@ -0,0 +1,14 @@
|
||||
import { el, on, dispatchEvent } from "deka-dom-el";
|
||||
document.body.append(
|
||||
el("p", "Listenning to `test` event.", on("test", console.log)).append(
|
||||
el("br"),
|
||||
el("button", "native", on("click", native)),
|
||||
" ",
|
||||
el("button", "dde", on("click", dde)),
|
||||
" ",
|
||||
el("button", "dde with options", on("click", ddeOptions))
|
||||
)
|
||||
);
|
||||
function native(){ this.dispatchEvent(new CustomEvent("test", { bubbles: true, detail: "hi" })); }
|
||||
function dde(){ dispatchEvent("test")(this.parentElement, "hi"); }
|
||||
function ddeOptions(){ dispatchEvent("test", { bubbles: true })(this, "hi"); }
|
18
docs_src/components/examples/events/live-cycle.js
Normal file
18
docs_src/components/examples/events/live-cycle.js
Normal file
@ -0,0 +1,18 @@
|
||||
import { el, on } from "deka-dom-el";
|
||||
const paragraph= el("p", "See live-cycle events in console.",
|
||||
el=> log({ type: "dde:created", detail: el }),
|
||||
on.connected(log),
|
||||
on.disconnected(log),
|
||||
on.attributeChanged(log));
|
||||
|
||||
document.body.append(
|
||||
paragraph,
|
||||
el("button", "Update attribute", on("click", ()=> paragraph.setAttribute("test", Math.random().toString()))),
|
||||
" ",
|
||||
el("button", "Remove", on("click", ()=> paragraph.remove()))
|
||||
);
|
||||
|
||||
/** @param {Partial<CustomEvent>} event */
|
||||
function log({ type, detail }){
|
||||
console.log({ _this: this, type, detail });
|
||||
}
|
@ -15,6 +15,18 @@ styles.scope(prevNext).css`
|
||||
}
|
||||
`;
|
||||
import { el } from "../../index.js";
|
||||
/**
|
||||
* @param {Object} attrs
|
||||
* @param {string} attrs.textContent
|
||||
* @param {string} [attrs.id]
|
||||
* */
|
||||
export function h3({ textContent, id }){
|
||||
if(!id) id= "h-"+textContent.toLowerCase().replaceAll(/\s/g, "-").replaceAll(/[^a-z-]/g, "");
|
||||
return el("h3", { id }).append(
|
||||
el("a", { textContent: "§", href: "#"+id, tabIndex: -1 }),
|
||||
" ", textContent
|
||||
);
|
||||
}
|
||||
/**
|
||||
* @param {import("../types.d.ts").Info} page
|
||||
* */
|
@ -3,7 +3,7 @@ import { el } from "deka-dom-el";
|
||||
|
||||
import { header } from "./layout/head.html.js";
|
||||
import { example } from "./components/example.html.js";
|
||||
import { prevNext } from "./components/prevNext.html.js";
|
||||
import { h3, prevNext } from "./components/pageUtils.html.js";
|
||||
|
||||
/** @param {string} url */
|
||||
const fileURL= url=> new URL(url, import.meta.url);
|
||||
@ -17,7 +17,7 @@ export function page({ pkg, info }){
|
||||
el("h2", "Native JavaScript DOM elements creations"),
|
||||
el("p", "Let’s go through all patterns we would like to use and what needs to be improved for better experience."),
|
||||
|
||||
el("h3", "Creating element(s) (with custom attributes)"),
|
||||
el(h3, "Creating element(s) (with custom attributes)"),
|
||||
el("p").append(
|
||||
"You can create a native DOM element by using the ",
|
||||
el("a", { href: "https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement", title: "MDN documentation for document.createElement()" }).append(
|
||||
@ -83,7 +83,7 @@ export function page({ pkg, info }){
|
||||
),
|
||||
el(example, { src: fileURL("./components/examples/elements/dekaAssign.js"), page_id }),
|
||||
|
||||
el("h3", "Native JavaScript templating"),
|
||||
el(h3, "Native JavaScript templating"),
|
||||
el("p", "By default, the native JS has no good way to define HTML template using DOM API:"),
|
||||
el(example, { src: fileURL("./components/examples/elements/nativeAppend.js"), page_id }),
|
||||
el("p").append(
|
||||
@ -92,7 +92,7 @@ export function page({ pkg, info }){
|
||||
el(example, { src: fileURL("./components/examples/elements/dekaAppend.js"), page_id }),
|
||||
|
||||
|
||||
el("h3", "Basic (state-less) components"),
|
||||
el(h3, "Basic (state-less) components"),
|
||||
el("p").append(
|
||||
"You can use functions for encapsulation (repeating) logic. ",
|
||||
"The ", el("code", "el"), " accepts function as first argument. ",
|
||||
@ -109,7 +109,7 @@ export function page({ pkg, info }){
|
||||
" and keep track of the native API (things are best remembered through regular use).",
|
||||
),
|
||||
|
||||
el("h3", "Creating non-HTML elements"),
|
||||
el(h3, "Creating non-HTML elements"),
|
||||
el("p").append(
|
||||
"Similarly to the native DOM API (", el("a", { href: "https://developer.mozilla.org/en-US/docs/Web/API/Document/createElementNS", title: "MDN" }).append(el("code", "document.createElementNS")), ") for non-HTML elements",
|
||||
" we need to tell JavaScript which kind of the element to create.",
|
||||
|
@ -3,7 +3,7 @@ import { el } from "deka-dom-el";
|
||||
|
||||
import { header } from "./layout/head.html.js";
|
||||
import { example } from "./components/example.html.js";
|
||||
import { prevNext } from "./components/prevNext.html.js";
|
||||
import { h3, prevNext } from "./components/pageUtils.html.js";
|
||||
|
||||
/** @param {string} url */
|
||||
const fileURL= url=> new URL(url, import.meta.url);
|
||||
@ -22,7 +22,7 @@ export function page({ pkg, info }){
|
||||
" incorporate not only this in UI templates declaratively."
|
||||
),
|
||||
|
||||
el("h3", "Events and listenners"),
|
||||
el(h3, "Events and listenners"),
|
||||
el("p").append(
|
||||
"In JavaScript you can listen to the native DOM events of the given element by using ",
|
||||
el("a", { href: "https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener", title: "addEventListener on MDN" }).append(
|
||||
@ -34,18 +34,33 @@ export function page({ pkg, info }){
|
||||
),
|
||||
el(example, { src: fileURL("./components/examples/events/compare.js"), page_id }),
|
||||
el("p").append(
|
||||
"…this is actually one of the two differences. The another one is that", el("code", "on"),
|
||||
"…this is actually one of the two differences. The another one is that ", el("code", "on"),
|
||||
" accepts only object as the ", el("code", "options"), " (but it is still optional)."
|
||||
),
|
||||
el("p").append(
|
||||
el("p", { className: "notice" }).append(
|
||||
"The other difference is that there is ", el("strong", "no"), " ", el("code", "off"), " function.",
|
||||
" ",
|
||||
"You can remove listener declaratively using ", el("a", { textContent: "AbortSignal", href: "https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#signal", title: "part of addEventListener on MDN" }),
|
||||
":"
|
||||
),
|
||||
el(example, { src: fileURL("./components/examples/events/abortSignal.js"), page_id }),
|
||||
el("div", { className: "notice" }).append(
|
||||
el("p", "So, there are (typically) three ways to handle events. You can use:"),
|
||||
el("ul").append(
|
||||
el("li").append( el("code", `el("button", { textContent: "click me", "=onclick": "console.log(event)" })`)),
|
||||
el("li").append( el("code", `el("button", { textContent: "click me", onclick: console.log })`)),
|
||||
el("li").append( el("code", `el("button", { textContent: "click me" }, on("click", console.log))`))
|
||||
),
|
||||
el("p").append(
|
||||
"In the first example we force to use HTML attribute (it corresponds to ", el("code", `<button onclick="console.log(event)">click me</button>`), ").",
|
||||
" ",
|
||||
el("em", "Side note: this can be useful in case of SSR."),
|
||||
" ",
|
||||
"To study difference, you can read a nice summary here: ", el("a", { href: "https://gist.github.com/WebReflection/b404c36f46371e3b1173bf5492acc944", textContent: "GIST @WebReflection/web_events.md" }), "."
|
||||
)
|
||||
),
|
||||
|
||||
el("h3", "Addons"),
|
||||
el(h3, "Addons"),
|
||||
el("p").append(
|
||||
"From practical point of view, ", el("em", "Addons"), " are just functions that accept any html element",
|
||||
" as their first parameter. You can see that the ", el("code", "on(…)"), " fullfills this requirement."
|
||||
@ -60,11 +75,44 @@ export function page({ pkg, info }){
|
||||
" ",
|
||||
"Also notice, you can use Addons to get element reference.",
|
||||
),
|
||||
el("h3", "Life cycle events"),
|
||||
el("p", "Addons are called immediately when the element is created, event it is not connected to live DOM yet."),
|
||||
// todo
|
||||
el(h3, "Life-cycle events"),
|
||||
el("p").append(
|
||||
"Addons are called immediately when the element is created, even it is not connected to live DOM yet.",
|
||||
" ",
|
||||
"Therefore, you can understand the Addon to be “oncreate” event."
|
||||
),
|
||||
el("p").append(
|
||||
"The library provide three additional live-cycle events corresponding to how they are named in",
|
||||
" a case of custom elements: ", el("code", "on.connected"), ", ", el("code", "on.disconnected"),
|
||||
" and ", el("code", "on.attributeChanged"), "."
|
||||
),
|
||||
el(example, { src: fileURL("./components/examples/events/live-cycle.js"), page_id }),
|
||||
el("p").append(
|
||||
"For Custom elements, we will later introduce a way to replace ", el("code", "*Callback"),
|
||||
" syntax with ", el("code", "dde:*"), " events. The ", el("code", "on.*"), " functions then",
|
||||
" listen to the appropriate Custom Elements events (see ", el("a", { textContent: "Custom element lifecycle callbacks | MDN", href: "https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks" }), ")."
|
||||
),
|
||||
el("p").append(
|
||||
"But, in case of regular elemnets the ", el("a", { href: "https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver" }).append(el("code", "MutationObserver"), " | MDN"),
|
||||
" is internaly used to track these events. Therefore, there are some drawbacks:",
|
||||
),
|
||||
el("ul").append(
|
||||
el("li").append(
|
||||
"To proper listener registration, you need to use ", el("code", "on.*"), " not `on(\"dde:*\", …)`!"
|
||||
),
|
||||
el("li").append(
|
||||
"Use sparingly! Internally, library must loop of all registered events and fires event properly.",
|
||||
" ",
|
||||
el("strong", "It is good practice to use the fact that if an element is removed, its children are also removed!"),
|
||||
" ",
|
||||
"In this spirit, we will introduce later the ", el("strong", "host"), " syntax to register",
|
||||
" clean up procedures when the component is removed from the app."
|
||||
),
|
||||
),
|
||||
|
||||
// dispatchEvent
|
||||
el(h3, "Final notes"),
|
||||
el("p", "The library also provides a method to dispatch the events."),
|
||||
el(example, { src: fileURL("./components/examples/events/compareDispatch.js"), page_id }),
|
||||
|
||||
el(prevNext, info)
|
||||
)
|
||||
|
@ -3,7 +3,7 @@ import { el } from "deka-dom-el";
|
||||
|
||||
import { header } from "./layout/head.html.js";
|
||||
import { example } from "./components/example.html.js";
|
||||
import { prevNext } from "./components/prevNext.html.js";
|
||||
import { prevNext } from "./components/pageUtils.html.js";
|
||||
|
||||
/** @param {import("./types.d.ts").PageAttrs} attrs */
|
||||
export function page({ pkg, info }){
|
||||
|
Reference in New Issue
Block a user