5 ms·
Oh please, if you want to compare, use modern vanilla too... <!doctype html> <body> <custom-element></custom-element> <script> const CHECKBOX_ID =
by atirip 5y ago
Oh please, if you want to compare, use modern vanilla too...
<!doctype html>
<body>
<custom-element></custom-element>
<script>
const CHECKBOX_ID = "my-checkbox";
const defaultLabelContent = "Toggle me, you newbies";
const beforeDiscountText = "You have not availabled discount";
const afterDiscountText = "Discount Availed!";
const beforeLabelText = "Click on me to remove fake discount"
const afterLabelText = "Click me to apply fake discount!"
const state = new WeakMap();
class CustomElement extends HTMLElement {
connectedCallback() {
this.render();
this.shadowRoot.addEventListener('change', (event) => {
state.set(this, event.target.checked);
this.render();
})
}
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
render() {
let isChecked = state.get(this);
const discountText = isChecked
? afterDiscountText
: beforeDiscountText;
const labelText = isChecked
? beforeLabelText
: afterLabelText;
this.shadowRoot.innerHTML = `
<input
${isChecked ? 'checked ' : ''}
type="checkbox"
id=${CHECKBOX_ID}
>
<label for=${CHECKBOX_ID}>
${labelText}
</label>
<div>${discountText}</div>
`;
}
}
customElements.define('custom-element', CustomElement);
</script>
- montenegrohugo 5y agoCodepen for this: https://codepen.io/uwwgo/pen/GRmEKJz https://codepen.io/uwwgo/pen/GRmEKJz (nothing revolutionary, does the exact same thing.)
- infensus 5y agoWell, technically it's not an equivalent as this would recreate dom nodes on every render
- atirip 5y agoThis was just taking the final React code in the article and rewriting it in vanilla as close as possible. Your comment is fully correct, but I would like to point out: - with such a tiny DOM to rerender, it is equivalent, probably even faster - custom element encapsulates DOM and it is fairly trivial and extremely fast to pick DOM (like you can even use id's everywhere) in the 'old jquery' way, with simple library functions - updating DOM with simple render() call is way more elegant, but if you keep custom elements DOM small (and one should), this way is not that bad at all Like this: <!doctype html> <body> <custom-element></custom-element> <script> const CHECKBOX_ID = "my-checkbox"; const defaultLabelContent = "Toggle me, you newbies"; const beforeDiscountText = "You have not availabled discount"; const afterDiscountText = "Discount Availed!"; const beforeLabelText = "Click on me to remove fake discount" const afterLabelText = "Click me to apply fake discount!" const state = new WeakMap(); // 'library' code function qs(selector) { return this.shadowRoot.querySelector(selector); } function getElem(nodeOrSelector) { return nodeOrSelector === String(nodeOrSelector) ? qs.call(this, nodeOrSelector) : nodeOrSelector; } function replaceText(nodeOrSelector, text) { let elem = getElem.call(this, nodeOrSelector); if (elem) elem.textContent = text; } function updateAttribute(nodeOrSelector, name, value = '') { let elem = getElem.call(this, nodeOrSelector); if (elem) elem[(value ? 'set' : 'remove') + 'Attribute'](name, value); } // end of 'library' code class CustomElement extends HTMLElement { connectedCallback() { this.attachShadow({ mode: 'open' }); this.shadowRoot.innerHTML = ` <input type="checkbox" id=${CHECKBOX_ID}> <label for=${CHECKBOX_ID}></label> <div></div> `; this.shadowRoot.addEventListener('change', (event) => { state.set(this, event.target.checked); this.update(); }) this.update(); } update() { let isChecked = state.get(this); updateAttribute.call(this, 'input', 'checked', isChecked); replaceText.call(this, 'label', isChecked ? beforeLabelText : afterLabelText); replaceText.call(this, 'div', isChecked ? afterDiscountText : beforeDiscountText); } } customElements.define('custom-element', CustomElement); </script>
- chrismorgan 5y ago> - with such a tiny DOM to rerender, it is equivalent, probably even faster I hope you’re comparing this to React? Because if you’re comparing it to vanilla JS that reuses the DOM nodes, absolutely not.
- peanut_worm 5y agoWhat does storing the state as a WeakMap do here?
- Ndymium 5y agoIf the custom DOM element is deleted, then its entry in the map will also be deleted. Otherwise it would hang around in the Map forever (unless manually deleted in a lifecycle callback).
- atirip 5y agoI initially just mimicked the React version into Vanilla, so this was a show-off how to do that somewhat exactly the same way. But in this particular case it serves no meaning, we can always read 'checked' from DOM.