3 ms·
Why would this make any sense? const myDiv = div( {id: 'container', className: 'my-class'}, h1('Hello World'), p('This is a dynamically
by tomp 2y ago
Why would this make any sense?
const myDiv = div(
{id: 'container', className: 'my-class'},
h1('Hello World'),
p('This is a dynamically generated paragraph.')
);
document.body.appendChild(myDiv);
That's completely unnecessary these days with template strings. It's gonna be much faster as well to use browser's native parsing.
const div = document.createElement('div');
let text = 'This is a dynamically generated paragraph';
div.innerHTML = `
<div id="container" class="my-class">
<h1>Hello world</h1>
<p>${text}</p>
</div>
`;
document.body.append(...div.children);
Keep it simple!
- franciscop 2y agoOne big difference and why I've been experimenting with JSX[1] is that in that example, if the `text` comes from an untrusted source it can lead to XSS, which TinyJS prevents (I checked)! [1] https://x.com/FPresencia/status/1838176000267452704 https://x.com/FPresencia/status/1838176000267452704
- wruza 2y agoEven if it comes from a trusted source, you usually want a good distinction between html interpolation and just-text chunks.
- spullara 2y agoyou should probably worry about untrusted data in text and use a tagged template function that sanitizes its inputs for insertion in html.
- deleted 2y ago[deleted]
- nikeee 2y agoYou can use tagged template functions to escape `${text}`. The result is pretty close to lit-html [1]. [1]: https://lit.dev/docs/v1/lit-html/introduction/ https://lit.dev/docs/v1/lit-html/introduction/
- tomp 2y agobeautiful!
- Nickersf 2y agoThis is exactly what I was thinking. I'm always trying to have fewer third-party dependencies in my codebase no matter how tiny, especially if it's solving problems that already have platform/system native solutions.
- rikafurude21 2y agoMakes sense to me, looks better. writing html strings like that is annoying
- TimTheTinker 2y agoGenerally, I would recommend avoiding directly setting the innerHTML property, since it's vulnerable to XSS and other injection attacks. If you do, make sure you HTML-escape each variable you interpolate. Here's a way to do that with a tagged template function (named it `htmlFragment` to make it super clear what it's for): // a couple of functions to help const sanitizeHTML = (unsafeStr) => { const div = document.createElement('div'); div.textContent = unsafeStr; return div.innerHTML; }; const htmlFragment = (fragments, ...variables) => { const result = variables.map((variable, i) => fragments[i] + sanitizeHTML(variable)); result.push(fragments[fragments.length-1]); return result.join(''); }; // updated your code here const div = document.createElement('div'); let text = 'This is a dynamically generated paragraph'; div.innerHTML = htmlFragment` <div id="container" class="my-class"> <h1>Hello world</h1> <p>${text}</p> </div> `; document.body.append(...div.children); Unfortunately, to my knowledge there isn't yet a close-to-the-metal solution for templating and data binding in HTML/JS, although several proposals are currently being discussed.
- meiraleal 2y ago> Unfortunately, to my knowledge there isn't yet a close-to-the-metal solution for templating and data binding in HTML/JS I'm hoping for this one: https://github.com/WICG/webcomponents/issues/1069 https://github.com/WICG/webcomponents/issues/1069
- makingstuffs 2y agoWould you not just be able to do the following: const div = document.createElement('div'); const text = 'This is a dynamically generated paragraph'; div.insertAdjacentHTML("beforeend", `<div id="container" class="my-class"> <h1>Hello world</h1> <p>${text}</p> </div>`); document.body.append(...div.children); Edit, figured I'd add the docs: https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML https://developer.mozilla.org/en-US/docs/Web/API/Element/ins...
- TimTheTinker 2y ago
- deleted 2y ago[deleted]
- spencerchubb 2y agohow would you add listeners if you were doing an html string? the first approach allows you to do something like this ``` const myButton = button({ onclick: e => console.log(e), textContent: "Click me" }) ```
- TimTheTinker 2y agoUse topElement.querySelector('button'), then add the listener programmatically.