JSFiddle - React, Tailwind, and code Playground
by alexb
HTML
<button id="addControl">Add control</button>
<div id="controlPanel"></div>
CSS
#controlPanel {
background: lightgray;
border: 1px outset;
margin: 1em 0;
padding: 1em;
}
.upcase {
text-transform: uppercase;
}
JavaScript
/**
* @param target {Node}
* @param selector {string}
* @param listener {(node: Node) => void)}
*/
function onChildNodeAdded(target, selector, listener) {
new MutationObserver((mutations, observer) => {
for (const mut of mutations) {
const el = mut.target.querySelector(selector);
if (el) {
observer.disconnect();
setTimeout(() => listener(el), 0);
return;
}
}
}).observe(target, { childList: true, subtree: true });
}
/**
* @param target {Node}
* @param listener {(node: Node) => void)}
*/
function onClassChanged(target, listener) {
new MutationObserver(mutations => {
setTimeout(() => listener(), 0);
}).observe(target, {
attributes: true,
attributeFilter: ["class"]
});
}
const add = document.getElementById('addControl');
const panel = document.getElementById('controlPanel');
add.addEventListener("click", e => {
const ctrl = document.createElement('button');
ctrl.innerText = 'Execute';
ctrl.className = 'ctrl';
ctrl.addEventListener("click", () => { ctrl.classList.toggle('upcase'); })
panel.appendChild(ctrl);
});
onChildNodeAdded(panel, '.ctrl', btn => {
onClassChanged(btn, e => {
console.log(btn.classList.contains('upcase') ? "what's updog?" : "not much. what's up with you?");
});
});