TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Mastering DOM manipulation with vanilla JavaScript

430 pointsby srirangrover 1 year ago

30 comments

snideover 1 year ago
Excellent list and examples. Browsing through a dozen or so of these I&#x27;m amazed at the care and detail in the examples. They are not only functional, but provide very solid UI work as well.<p>As I&#x27;ve shifted away from platforms like React to smaller, minimalist implementations, I often have trouble finding ways for how to do complex patterns in standard JS. It&#x27;s funny when you look at the code and think... huh, that&#x27;s actually a lot easier than importing a huge library with way too many props :)<p>Thanks to the author for putting this together.
评论 #38162853 未加载
评论 #38163599 未加载
danielvaughnover 1 year ago
So I’m working on this side project. I don’t have a name for it yet but I’ve been describing it as “vim for web designers”. The idea is that you can build a website (or components) in the browser, similar to Webflow, but it’s entirely driven by a command language.<p>When I began the project, I told myself I wasn’t going to use a framework. After all, I’ve been doing this since 2009, I was working with JS for a long time before I ever touched a framework. And besides, the native DOM APIs have long been good enough. Right?<p>My god, it was an absolute slog. Marshalling data into and out of the DOM is so tedious and error prone that I began writing my own mini framework to save my own sanity. And then I remembered why I began using frameworks to begin with - because ultimately you’re going to be using a framework of some kind regardless, it’s just whether you want your own custom one or a community-built industry standard.<p>I do still think native DOM is great, if you’re working with small amounts of interactivity. Most sites that use React probably don’t need it. But if your product has even a little bit of nuance or complexity, I’d go with a framework and avoid the hassle.<p>In the end I migrated to Svelte, and I’m much happier as a result.
评论 #38164147 未加载
评论 #38162872 未加载
评论 #38164223 未加载
评论 #38163039 未加载
panziover 1 year ago
`value.startsWith(&#x27;javascript:&#x27;)` and there you have a vulnerability. There can be arbitrary white-space before the URL, so you&#x27;d need to do `value.trim().startsWith(&#x27;javascript:&#x27;)` instead. However, I much prefer white listing instead, i.e. only allowing `http:`, `https:` and maybe `mailto:`, `ftp:`, `sftp:` and such. Maybe allow relative URLs starting with `&#x2F;`. Maybe. Though that would mean to correctly handle all attributes that actually can be URLs. Again, I&#x27;d just white list a few tags plus a few of their attributes.
评论 #38163949 未加载
评论 #38163658 未加载
flanbiscuitover 1 year ago
Seems like a helpful list of things to know, I haven&#x27;t gone through it all but looks good so far.<p>Clicked on the first one and I noticed something.<p>They write this:<p><pre><code> const setFavicon = () =&gt; { const favicon = document.querySelector(&#x27;link[rel=&quot;icon&quot;]&#x27;); favicon.href = (window.matchMedia(&#x27;(prefers-color-scheme: dark)&#x27;).matches) ? &#x27;dark-mode-favicon.png&#x27; : &#x27;light-mode-favicon.png&#x27;; }; setFavicon(); </code></pre> And then this:<p>&gt; We can use this function to update the user&#x27;s color scheme preference whenever they make a change.<p><pre><code> window .matchMedia(&#x27;(prefers-color-scheme: dark)&#x27;) .addEventListener(&#x27;change&#x27;, setFavicon); </code></pre> They are running &quot;window.matchMedia(&#x27;(prefers-color-scheme: dark)&#x27;)&quot; twice unnecessarily. If you&#x27;re going to run `setFavicon` as the callback to the event listener, you can get the result from the `event` parameter passed to the callback like this:<p><pre><code> const setFavicon = (event) =&gt; { const favicon = document.querySelector(&#x27;link[rel=&quot;icon&quot;]&#x27;); favicon.href = event.matches ? &#x27;dark-mode-favicon.png&#x27; : &#x27;light-mode-favicon.png&#x27;; </code></pre> This would be my preferred way of doing it because it supports users who are visiting with JS disabled.<p><pre><code> &lt;link href=&quot;light-mode-favicon.png&quot; rel=&quot;icon&quot; media=&quot;(prefers-color-scheme: light)&quot;&gt; &lt;link href=&quot;dark-mode-favicon.png&quot; rel=&quot;icon&quot; media=&quot;(prefers-color-scheme: dark)&quot;&gt; </code></pre> <a href="https:&#x2F;&#x2F;phuoc.ng&#x2F;collection&#x2F;html-dom&#x2F;change-the-favicon-dynamically-based-on-user-color-scheme-preference&#x2F;" rel="nofollow noreferrer">https:&#x2F;&#x2F;phuoc.ng&#x2F;collection&#x2F;html-dom&#x2F;change-the-favicon-dyna...</a>
评论 #38163748 未加载
throwaway858over 1 year ago
The technique for &quot;Make a textarea auto-expand&quot; is obsoleted by a new CSS property(&quot;form-sizing&quot;):<p><a href="https:&#x2F;&#x2F;chriscoyier.net&#x2F;2023&#x2F;09&#x2F;29&#x2F;css-solves-auto-expanding-textareas-probably-eventually&#x2F;" rel="nofollow noreferrer">https:&#x2F;&#x2F;chriscoyier.net&#x2F;2023&#x2F;09&#x2F;29&#x2F;css-solves-auto-expanding...</a><p>Even without using this new CSS property, the technique that is used (adjusting the &quot;height&quot; of the element) is not ideal and can be glitchy.<p>A better approach is to use a mirror hidden element:<p><a href="https:&#x2F;&#x2F;css-tricks.com&#x2F;the-cleanest-trick-for-autogrowing-textareas&#x2F;" rel="nofollow noreferrer">https:&#x2F;&#x2F;css-tricks.com&#x2F;the-cleanest-trick-for-autogrowing-te...</a>
bakkotingover 1 year ago
A number of these are using older, awkward APIs, when there&#x27;s nicer native versions now.<p>For example, &quot;replace an element&quot; is<p><pre><code> ele.parentNode.replaceChild(newEle, ele); </code></pre> but unless you&#x27;re targeting Chrome &lt; 54, FF &lt; 49, or Safari &lt; 10, you can just do<p><pre><code> ele.replaceWith(newEle) </code></pre> `replaceWith` also lets you replace a node with _multiple_ nodes, or with text.<p>Similarly, &quot;loop over a nodelist&quot; wants you to use array spread and then forEach, instead of just<p><pre><code> for (let ele of nodelist) ...</code></pre>
评论 #38166374 未加载
cmrdporcupineover 1 year ago
Nice. Bookmarked. Another good one in a similar vein is <a href="https:&#x2F;&#x2F;youmightnotneedjquery.com&#x2F;" rel="nofollow noreferrer">https:&#x2F;&#x2F;youmightnotneedjquery.com&#x2F;</a><p>I don&#x27;t do web stuff often, but when I do I am <i>completely</i> demoralized by the state of framework-itis there. It&#x27;s gotten completely out of control. A fresh React project is hundreds of dependencies. The weight of that complexity is astounding to me.<p>Meanwhile the core cross-platform browser tech shipped by default has never been more capable and the amount of code to do common things ... isn&#x27;t very much.<p>Front-end devs: are you ok?
评论 #38163471 未加载
评论 #38163700 未加载
评论 #38163416 未加载
评论 #38164915 未加载
blablabla123over 1 year ago
What really blew my mind was when I found out that many of the DOM functions return live HTMLCollections that are automatically updated. I wonder how often that feature is being actively used in production code (before the framework craze or developing with no framework being somewhat more popular again)
fatnoahover 1 year ago
What&#x27;s old is new again. My first front-end role was building web applications wayyyyy back in 1999. Everything was done with &quot;Vanilla&quot; JS, including fancy stuff like drag and drop in a treeview, click to edit, building what effectively was a single page app, etc. etc. The hardest part was negotiating the differences between Netscape and Internet Explorer.
评论 #38175936 未加载
russellbeattieover 1 year ago
My new favorite bit of vanilla JavaScript has been around since Chrome 1.0 and IE: Element.insertAdjacentHTML. To say it&#x27;s useful is an understatement, especially with multi-line Strings using `. I can&#x27;t believe it&#x27;s been around so long and I only realized it a year or so ago.<p><i>The insertAdjacentHTML(position, text) method of the Element interface parses the specified text as HTML or XML and inserts the resulting nodes into the DOM tree at a specified position.</i><p>A contrived example of something that&#x27;s a pain to do with raw DOM:<p><pre><code> let anchors = [&#x27;#a&#x27;, &#x27;#b&#x27;, &#x27;#c&#x27;]; let el = document.querySelector(&#x27;ul&#x27;); for (let a of anchors) { el.insertAdjacentHTML( &#x27;beforeend&#x27;, `&lt;li&gt;&lt;a href=&quot;${a}&quot;&gt;${a.substr(1)}&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;` ); } </code></pre> Previously I would have to create the li element, then the a element, add it as a child, set the href attribute, then the text value of the a element, then insert it into the ul element. Or, I&#x27;d batch it all up as a big string and insert it using innerHTML. Modifying an existing list was even more painful and verbose.<p>1. <a href="https:&#x2F;&#x2F;developer.mozilla.org&#x2F;en-US&#x2F;docs&#x2F;Web&#x2F;API&#x2F;Element&#x2F;insertAdjacentHTML" rel="nofollow noreferrer">https:&#x2F;&#x2F;developer.mozilla.org&#x2F;en-US&#x2F;docs&#x2F;Web&#x2F;API&#x2F;Element&#x2F;ins...</a>
tolmaskyover 1 year ago
These are great. It&#x27;s unfortunate that if there&#x27;s any minor bugs there&#x27;s no way to really keep in sync though, for example the security issue mentioned in another comment in these comments. It would be cool if these examples could be wrapped up into some sort of convenient &quot;package&quot; or something like that, such that you could easily know if there are any updates and grab them, as well as just make it easier to grab these functions whenever you need them instead of copy-pasting them...
beardywover 1 year ago
I am a great fan of vanilla JavaScript so for me it is a great resource. Sadly many js developers nowadays don&#x27;t really understand what the Dom can do for them. A great resource!
alin23over 1 year ago
yeaaaaaaah no. Never going this path again for any interactive page.<p>This summer I built an irrigation system for my father&#x27;s field, with the idea that the scheduling would be done in relative time (water this zone for 2h) instead of absolute (start watering this zone at 9AM and end at 11AM).<p>I kept it as simple as possible:<p><pre><code> - 16 cheap relays for the 24V AC electric valves - 1 beefy relay for the pump - 1 Pi Pico W for controlling the relays </code></pre> Here&#x27;s a picture of the &quot;low-tech&quot; build: <a href="https:&#x2F;&#x2F;files.alinpanaitiu.com&#x2F;lowtech-irigation.jpeg" rel="nofollow noreferrer">https:&#x2F;&#x2F;files.alinpanaitiu.com&#x2F;lowtech-irigation.jpeg</a><p>The Pico W would have a <i>code.py</i> with all the relay and schedule logic, and an <i>index.html</i> which would be a simple list of sliders to set how much time each valve should be open. The Pico W would function as a &quot;hotspot&quot; which the phone would connect to, and the &quot;app&quot; would be available at 192.168.4.1.<p><i>It can be added to homescreen and it looks just like a native app as far as my father is concerned. It doesn&#x27;t feel like one though, he can tell.</i><p>The web page looks like this: <a href="https:&#x2F;&#x2F;shots.panaitiu.com&#x2F;lHMGplFn" rel="nofollow noreferrer">https:&#x2F;&#x2F;shots.panaitiu.com&#x2F;lHMGplFn</a><p>That&#x27;s all there is to it, really. That <i>simple</i> single page with a few sliders and buttons took weeks to build and test thoroughly with only vanilla JS. I was obviously constrained by the flash memory, but there are KB-sized helper frameworks nowadays which I wasn&#x27;t aware of.<p>It&#x27;s also really hard to refactor. I initially stored the schedules at minute-resolution, but then had to store it in second-resolution to add a <i>repeat schedule</i> feature. Oh boy, so much code to parse and change, so many slider.value calculations to redo... yep, never doing this again
评论 #38163791 未加载
评论 #38166148 未加载
评论 #38166819 未加载
mgover 1 year ago
These days, I get by with just two dependencies. One is dqs.js:<p><a href="https:&#x2F;&#x2F;github.com&#x2F;no-gravity&#x2F;dqs.js">https:&#x2F;&#x2F;github.com&#x2F;no-gravity&#x2F;dqs.js</a><p>Which turns document.querySelector(&#x27;.some .thing&#x27;) into dqs(&#x27;.some .thing&#x27;).<p>The other one is Handlebars:<p><a href="https:&#x2F;&#x2F;github.com&#x2F;handlebars-lang&#x2F;handlebars.js&#x2F;">https:&#x2F;&#x2F;github.com&#x2F;handlebars-lang&#x2F;handlebars.js&#x2F;</a><p>Which I use for all my frontend templating needs.
评论 #38163019 未加载
评论 #38163663 未加载
评论 #38162991 未加载
评论 #38163011 未加载
评论 #38163545 未加载
kossTKRover 1 year ago
Great resource! I&#x27;ve defaulted to just use vanilla js and petite-vue, it&#x27;s 15 kilobytes and gives a good base.<p>The problem is the build requirements you run into quickly if you want to use plugins these days with vanilla js.<p>Elegance was being able to load actual modules from a CDN. Why did we need these anti-web build steps on top of JS?<p>I feel like there was a sweet spot of complexity around Vue 1 or say 2014.<p>The Vue 2--&gt;3 jump illustrates the welcome but total breakdown of frameworks in my opinion. It constantly gets in your way and moving data on a page with a hierarchy you need some bizarrely complex data flow, so many folders, files, tools, brittle typescript linting, &quot;auto&quot; this and that, constant building and so many rules it&#x27;s not fun to engineer anymore.<p>Anyway, i think we are very close to a sweet spot if we just use something like Petite-vue &#x2F; Alpine on top of JS maybe with a tiny router and get creative with JS around that, or just early versions say Vue if we need anything more complex.
评论 #38167403 未加载
bobmaxupover 1 year ago
If I were making a cookbook on HTML&#x2F;JS I would probably leave out this:<p><a href="https:&#x2F;&#x2F;phuoc.ng&#x2F;collection&#x2F;html-dom&#x2F;sanitize-html-strings&#x2F;#eliminating-the-script-tags" rel="nofollow noreferrer">https:&#x2F;&#x2F;phuoc.ng&#x2F;collection&#x2F;html-dom&#x2F;sanitize-html-strings&#x2F;#...</a>
评论 #38163464 未加载
评论 #38163735 未加载
评论 #38164534 未加载
gwbas1cover 1 year ago
FYI: Understanding some very basic DOM manipulation is important even if you are working with very modern tools.<p>Case in point: I&#x27;m working on a shipping Blazor WASM application, and I&#x27;ve had to drop into the DOM twice:<p>1: We&#x27;re still using Leaflet.js for a map component. This occasionally requires some DOM calls to adapt between Blazor&#x27;s worldview and Leaflet&#x27;s worldview.<p>2: Blazor WASM loads slowly, so we put up a splash animation in HTML. Removing the splash animation at the &quot;right&quot; time requires DOM manipulation. (Because we want to keep the splash animation up while the Blazor side makes additional calls, so we use DOM manipulation to hide the Blazor-based UI until we&#x27;ve loaded everything.)
DerekBickertonover 1 year ago
For syntactic DOM manipulation sugar I use Cash[0]<p>[0] <a href="https:&#x2F;&#x2F;kenwheeler.github.io&#x2F;cash&#x2F;" rel="nofollow noreferrer">https:&#x2F;&#x2F;kenwheeler.github.io&#x2F;cash&#x2F;</a>
jampekkaover 1 year ago
I appreciate the benefit of not having dependencies but not a fan of this rabid vanilla fixation.<p>Of course you can do anything with Vanilla that you can do with e.g. jquery. Otherwise jquery obviously couldn&#x27;t do it.<p>The problem is that the vanilla DOM API sucks. document.getElementById sucks vs $, document.querySelector sucks vs $. setTimeout and setInterval suck. addEventHandler really sucks.
earthboundkidover 1 year ago
<a href="https:&#x2F;&#x2F;phuoc.ng&#x2F;collection&#x2F;html-dom&#x2F;resize-an-iframe-to-fit-its-content&#x2F;" rel="nofollow noreferrer">https:&#x2F;&#x2F;phuoc.ng&#x2F;collection&#x2F;html-dom&#x2F;resize-an-iframe-to-fit...</a><p>There should be a way to do this with CSS and maybe some magic headers. It&#x27;s super annoying that it has be done via JS.
jeffgrecoover 1 year ago
This looks like some helpful refreshers as I try and mess with building a browser extension.
marbanover 1 year ago
All good except for <i>Create a custom scrollbar</i>
sumoboyover 1 year ago
Same developer who has offers a form validator, very solid and was worth the $ for past projects. Nice list of JS snippets.
agumonkeyover 1 year ago
Very nice list, it&#x27;s nice to &quot;down to earth&quot; after too much react ui libs :). Thanks.
wangiiover 1 year ago
so, after 10 years of reactjs, we&#x27;ve forgot how to do this in javascript?
purplecatsover 1 year ago
what is the value in manually processing knowledge bases like this (besides perhaps in an artisan fashion) if your knowledge interface such as chatgpt already knows it and surfaces it at will?
评论 #38169071 未加载
评论 #38168077 未加载
评论 #38168088 未加载
estover 1 year ago
Is there a CSS version of this? Like Zen-garden but modern
throw555chipover 1 year ago
AI models will no doubt gobble it up and spit out back out in a unique looking laundered format minus the comments.
Ringzover 1 year ago
Just use HTMX
selimnairbover 1 year ago
In Capitalist America, DOM manipulates you!