
How to manage HTML DOM with vanilla JavaScript only? - velmu
https://htmldom.dev/
======
davnicwil
Great resource, I've bookmarked it.

You know where vanilla JS still has a legitimate usecase in the era of SPAs?
Landing pages.

\- Mostly static HTML, time to first render is critical, all you want is a
little bit of (progressively added) flair

\- Can be inlined for instant loading/execution, no bundle download (or SSR)
necessary

\- Code has low volume and scope so structure / spaghetti isn't a concern

\- You can separate it out from the rest of your SPA bundle(s), so shipping
changes is completely decoupled from your SPA CI/CD process and can be done as
frequently as you like and _very_ quickly

~~~
satvikpendem
Yes, landing pages are places where you can use static HTML, CSS, and JS.
However, React (and similar frameworks) might still be better, especially with
a landing page with multiple parts. This is because React combines two
different paradigms, one of creation and one of distribution.

In creation, React breaks up large parts into smaller components. In
distribution, it renders them at runtime, not build time (with a standard
create-react-app app). However, there is no reason to have both at once.
Components make the page easy to reason about, and they can be used to compile
a site at build time, as Svelte does. React also has its own libraries for
this, like Gatsby and Next JS. You do say that the landing pages have low
volume but they can certainly grow to encompass a larger amount of things,
such as multiple feature pages or a blog, so I'd rather not rewrite everything
later on.

You could also use Web Components but they don't have as much support and are
generally not as good as React (one can disagree of course), so I like to use
React + Gatsby to build the pages at compile time and use them without any
Javascript whatsoever [0] but still have the developer experience of creating
a page via components.

[0] [https://www.gatsbyjs.org/packages/gatsby-plugin-no-
javascrip...](https://www.gatsbyjs.org/packages/gatsby-plugin-no-javascript/)

~~~
brailsafe
I really feel like React and components in general, or almost any framework is
probably overkill for most basic websites and even apps can make things harder
to reason about than previous architecture styles. Especially so if there is a
tendency to decouple at a very granular level.

~~~
andykx
I recently decided to, for the sake of practice, build some single page apps
using Vanilla JS. It was such a pain. Maybe some of it is due to my relative
lack of front-end JS experience, but I found it nearly impossible to avoid
duplicate code. I’m interested to know how people architected apps like that
before. I was under the impression that SPAs were not nearly as common before
frameworks like React.

~~~
kls
There where other toolkits before react, Dojo, MooTools, YUI each had their
pros and cons. The problem was they where all fiefdoms similar to how Angular
is. Where React really hit while the iron was how was that the whole
JavaScript build and packaging system was moving to npm and react was one of
the first sane component models available in that ecosystem. Unlike the
previous attempts React did not try to be all things to all people, it was
laser focused on being a component model and life-cycle. You got the rest via
a plethora of options via npm install.

As a side not React also bucked what was the sage wisdom of the time which
was, don't mix templates with code via the introduction of JSX. This came from
the very real and sage pattern of separation of concerns but somewhere along
the way we confused separations of technologies with separations of concerns.
If a piece of CSS, a piece of HTML and a piece of JS are all dealing with the
same black box concern and are not reusable outside of that black box,
separation of technologies (i.e separate files for each) only serves to add
complexity to the solution as it abstracts them away from each other, forces
the need to resolve their interdependence and obfuscates the ability to
quickly get an entire overview of the black box.

------
zoom6628
This site is a real gem. Clean, simple, and minus the excessive complexity and
obfuscation caused by frameworks. Doing & Learning things in plain JS we can
learn fundamentals.

~~~
dgb23
I agree!

The MDN docs are from my experience the best browser frontend reference
available.

This site however covers a different need: guide/howto oriented documentation,
which is often what you want.

> Doing & Learning things in plain JS we can learn fundamentals.

To this I have to add that I often do write plain JS supported by only a few,
small libraries such as is.js, axios, json-schema and so on. This is regarding
small to medium sized projects and/or features.

This can easily save time, setup and mental energy, as long as one follows a
consistent, simple structure. And on top of that, the fewer dependencies you
have, the less friction.

But it also means that one has to have a bit of a deeper knowledge of the
available frameworks and tools, which can manage complexity with growing
features, because you add them incrementally and only when needed and so on.

~~~
Kwantuum
Honestly, while axios is nice to have on the server side, the websocket API in
the browser is very simple to use. Which IMO is a consistent theme with modern
browser APIs.

~~~
girvo
Agreed: on our current front end project at work I’m having a lot of fun
teaching the team the amazing browser APIs that subsume the need for a lot of
the third party dependencies we used to reach for

~~~
orange8
How do you deal with IE 11?

~~~
girvo
In this project, simple: we don't have to. Despite being a decade old
application, it was entirely AJAX-driven and front-end focused even back in
2010, and IE support was dropped entirely a few years ago by the business.
Works in Edge just fine, as to be expected

~~~
orange8
Makes sense. I think the two options are just dropping IE support entirely or
using (usually third-party) polyfills.

------
vbezhenar
The problem with vanilla JS is not APIs, API is the easy thing. The problem is
building proper architecture, so code won't quickly turn into spaghetti. With
frameworks like Angular or React, it's much easier, as the general structure
is dictated by framework and developer just have to follow good practice. With
vanilla JS it's the wild west.

~~~
austincheney
> With vanilla JS it's the wild west.

In my experience in the corporate world it's just as much the wild west even
with using popular frameworks. Frameworks aren't a substitute for discipline
or organization.

~~~
a_wild_dandan
I wonder if those chaotic corporate experiences would've been far worse if not
for the frameworks. They're just so useful for significantly constraining the
solution space that you can't get _too_ far into the weeds even when lacking
discipline/organization.

~~~
corebit
My experience is that velocity slows because devs get so lost in all the
accidental complexity of these frameworks and their hidden lifecycles (that
they only barely grasp from their 1 tutorials worth of experience) that their
velocity of delivering real business value plummets. We are much less
productive than a decade ago.

~~~
nicoburns
Did you ever work on a JQuery codebase? (JQuery was an almost 1:1 mapping to
browser APIs, do it's more or less equivalent to vanillaJS). Codebases based
on modern frameworks, especially React, are _much_ less complex than codebases
based on the old approach. Back then you'd get lost in the weeds of DOM
manipulation, and it'd be hard to see the big picture at all.

In my experience most of the incidental complexity in modern apps comes from
inexperienced devs doing things that simply didn't need to be done in the
first place. Very little of it comes from the frameworks.

~~~
yitianjian
I also feel modern web apps are just much more complex than those from the
jQuery era. So codebases have to do a lot more. It's hard to find a 1:1
mapping, as we just didn't expect as much out of the web in those days.

~~~
TedDoesntTalk
Complete BS. Not true at all. the jquery era had ajax with dynamic dom
updates, dynamic svg, css, and many things we have today except for
websockets, web usb, mic, camera, and other devices. the difficulty was more
around each browser implementing things differently. and css was a nightmare.
just to center something horizontally or vertically (or both) took patience.

~~~
girvo
It’s not “Complete BS.” — just because we had those features does _not_ mean
most businesses used them to the same extent we do today. I was deep in the
front-end weeds in 2007 and onwards, and while I may have been doing some neat
stuff then, the complexity pales in comparison to the sheer amount of business
logic that now lives client-side.

~~~
TedDoesntTalk
That's because you have 13 more years of experience now. Or you like to revise
history.

------
Leace
Interesting pattern, first time I saw this:

    
    
            switch (true) {
                case cellA > cellB: return 1;
                case cellA < cellB: return -1;
                case cellA === cellB: return 0;
            }
    

Source: [https://htmldom.dev/sort-a-table-by-clicking-its-
headers](https://htmldom.dev/sort-a-table-by-clicking-its-headers)

~~~
XCSme
I think you can just do:

    
    
        if (cellA > cellB) return 1;
        if (cellA < cellB) return -1;
        if (cellA === cellB) return 0;
    

Why is the switch better? Or even (less explicit, but shorter code):

    
    
        if (cellA === cellB) return 0;
        return cellA > cellB ? 1 : -1;

~~~
marcus_holmes
Switch statements indicate "it's one of these things", whereas in the series
of ifs any of them could be true. Using a switch statement tells the reader
that you expect one of these things to happen [0]. Using a series of ifs tells
the reader that these things might or might not happen depending, and they're
going to have to read each statement to work out which.

Your last version doesn't tell the reader what your intention is at all, and
they need to work out what you're trying to do here. It's a lot less readable.
Unless you're desperate for those bytes, it'd be better to use the switch
statement for this case.

[0]: This gets a little weird in languages like JS where switch statements
fall through to the next one if you don't break or return, but generally it
still holds true.

~~~
jannes
With if you can also indicate "it's one of these things" by throwing an error
at the end:

    
    
        if (cellA > cellB) return 1;
        if (cellA < cellB) return -1;
        if (cellA === cellB) return 0;
        throw new Error();

~~~
bluedino
Let me tell you about if..else!

------
droobles
I do all my personal mvps now in vanilla JS, I can get ideas fleshed out
faster without fumbling over frameworks.

~~~
mschuster91
Out of random interest, not even jQuery? I find it immensely tedious to write
out vanilla js compared to all the shortcuts that $ provides...

~~~
mellow2020
Knowing that jQuery ends up calling those very same functions, only often
after jumping through a bunch of hoops, doesnt make me consider it a shortcut.
Between auto-complete and copy and paste, I prefer slightly more "work" up
front, and then zero needless work at runtime, than a bit of "magic" that ends
up doing needless work every single time it is run.

But I have to admit, I don't care about compatibility beyond Firefox on the
desktop, if I wrote stuff for a company on a deadline, or if I worked with
other people on something, I would mind jQuery very little or not at all. But
for my own stuff I make to spark joy, where I get to decide all of it, I want
it as vanilla as I can get it.

~~~
no_wizard
> copy and paste

Bravo for admitting it. I have to say I've usually run into trouble working
with copy and paste coders though.

How do you make sure what you're doing this with is something you understand?
I never understood this one.

~~~
mellow2020
I just meant copying and pasting long function and variable names out of my
own code elsewhere, should autocomplete somehow not apply.

------
tabtab
Making decent UI's went from bicycle science to rocket science. VB-classic was
easy to learn and easy to use, and you had coordinate control over where most
things went on the screen. If your layout engine didn't put it where you had
planned, you can just tell the widget to "go right here". You felt in charge
of the screen, not some abstract layout layer with an attitude. A manager
(person) could draw something on the back of a napkin and you could make it
_exactly_ match the napkin because you were in charge of exactly where things
went. (Layout engines were optional then.)

The newer UI frameworks are round-about and confusing. They make it easy to
get 80% of what you want, but that last 20% is bear, requiring long trial-and-
error periods, unless you are heavily versed in them. Abstraction is only nice
when it does what you want, not when it becomes "abstract art".

The price for "responsive" (client-side auto-placement) has been huge. In
applications that are primarily for office desktops, their advantage is lost.
Mouse and PC's is still where most real work is done. Instead we are using
things like Bootstrap, designed for social networks, not real work. Glamour
won over logic.

It's great job security for UI experts, but expensive for organizations
because they need stack specialists whereby before a one-man-band (or 2) could
make useful apps for less than half the cost and time without having to spend
years with UI-Yoda to master some screwy layout engine.

Something is wrong.

~~~
protonimitate
This argument is typical hackernews upvote bait.

You can't honestly compare VB UI's to modern day web UI with a straight face.
Following your analogy, making decent UIs is closer to rocket science because
web apps are closer to rockets than bicycles these days.

I would love to see a drag-n-drop approach to web UI building that is
responsive and fast. But I highly suspect the reason this doesn't exist isn't
"great job security".

There's really nothing complex or difficult enough in React, Vue, or any other
UI framework that can't be picked up by a competent dev quickly.

>Something is wrong

Yeah, the hivemind that loves to hate anything JS/front-end related and things
"purity" is the only bar by which to measure things.

~~~
mb7733
> There's really nothing complex or difficult enough in React, Vue, or any
> other UI framework that can't be picked up by a competent dev quickly.

Honestly. Where I work we have a few undergrad co-op students who have just
finished their first year of school. No previous React experience. They jumped
right in and were useful on our React projects after about week. They just
read some docs, asked a couple questions and played with our existing code.
They're smart people but they're not x10 programmers.

We have other large projects that are a more "traditional" mix of DOM
manipulation use jQuery, global CSS, etc. and introducing new hires to that is
never as smooth. There are no docs as thorough as React's that explain the
patterns established in those codebases (if there are any consistent patterns
at all).

One thing to note, we make what I would consider to be web applications (for
data management & analysis), not web pages.

------
jancsika
> This approach isn't recommended because we can only attach one handler for
> each event.

Except when you _do_ want that behavior. E.g., you only want to set one
listener and have a stream of data coming in that can trigger various
attachments/detachments to the same element(s) over and over.

With the ancient "on" methods you get a single method that you can replace at
will. Unbinding happens automatically. For example, you can keep assigning to
an anonymous function till your heart's content and there will only ever be
one callback in that slot attached as the author states.

With the new, "recommended" methods you must manually track the state and
unbind old callbacks. For example, you would have leaky behavior if you kept
assigning anonymous functions with addEventListener. And you can't easily hack
your way out of the state problem because the DOM doesn't give you a way to
fetch the current number of listeners, reset them to default or really know
anything about them.

So the recommended behavior does not include in its design the ability to
achieve the useful old behavior.

But at least DOM does have a convenience method to toggle class that will save
a good 10 seconds per year of dev time.

~~~
tln
What's the context for that quote? The main page of the linked site doesn't
have it.

I was wondering something similar while looking at
[https://htmldom.dev/toggle-password-visibility](https://htmldom.dev/toggle-
password-visibility)

This could be done inline with <input type="password" id="password" /> <button
onclick="password.type = password.type == 'text' ? 'password' :
'text'">Toggle</button>

...instead of 10 lines of code. Is it ever ok to use the fact that
window.elementID works? even for exposition? (it works in all browsers, not
sure if its standardized...) Why use setAttribute? Again, setting via
element.type = ... works in all browsers.

~~~
austincheney
It does. [https://htmldom.dev/attach-or-detach-an-event-
handler](https://htmldom.dev/attach-or-detach-an-event-handler)

The idea behind addEventListener is that multiple handlers can be attached to
the same event of the same node, whereas before handlers were property
assignments that would clobber each other.

The disadvantage of addEventListener is that event handlers are associated
with event listeners instead of with DOM nodes, which makes them more
challenging to garbage collect and thus increases the memory space of your
application. The way to keep the code clean is to use _removeEventListener_
when the handler is no longer needed. Event handlers are rarely removed from
the code though, because of a lack of discipline and because many times its
hard to tell when they are no longer needed.

The biggest advantage of assignment by property approach is that it imposes
simplicity. Simplify means _to make fewer_ and complicate means _to make
many_. When there is only one handler it is inherently the most simple
approach, which greatly increases code cleanliness and forces a greater
concern of code organization.

~~~
edflsafoiewq
Another possible advantage for onevent properties is they work as soon as the
element is loaded. Attaching event listeners normally has to wait for the
whole DOM to be loaded. The difference probably isn't noticeable over a good
connection.

------
austincheney
Coincidentally, I just commented yesterday about an interview experience I had
about the DOM. I did not expect it to be so highly upvoted.
[https://news.ycombinator.com/item?id=22740897](https://news.ycombinator.com/item?id=22740897)

~~~
dahart
I don’t know if I would pass your test, but the outcome is more or less
exactly what I would have expected. The vast majority of employed web devs do
not use pure JS to manipulate the DOM because it’s incredibly tedious. That
was true 5-10 years ago when the most popular option was JQuery, and now we
have massive swaths of React where people don’t manipulate the DOM directly at
all. And they get by _just fine_. Major commercial sites are built with little
to no direct DOM manipulation.

Saying that you’re going to let people have time, use the web to lookup the
answer, that there’s no penalty, etc., that seems blind to the fact that
you’re signaling what it takes to pass the test as well as what people will be
doing once they start working for you. I’m certain you lost the opportunity to
interview some good candidates simply because they are choosing to not work
somewhere that thinks pure JS is the only performant solution, and might not
know that there are both good and bad ways to use JQuery, and/or functional
reactive solutions that avoid keeping messy/buggy state around when you could
instead re-render. I’m sure you also lost interviews because some candidates
were basically told by you that already knowing how to manipulate the DOM via
pure JS was what was required to ace the interview. They assumed, and
reasonably so, that spending the hour showing you they didn’t already know how
would result in not getting a job, so why bother with the interview right now?
You might have sent several smart people off to study and do homework about
it, but you don’t know that because they walked out the door.

So, while I do think it’s very useful to know how to use pure JS on the DOM,
and I think your interview experience is interesting, the incredulity about it
makes it seem to me like you’re not entirely taking responsibility for the
implicit message that you sent to your candidates for the interview, nor that
the outcome is fairly predictable.

~~~
austincheney
The job position was for people to write A/B tests. A/B tests are a form of
white hat hacking where code is injected into a page to manipulate or deface
the page to test a business idea as an experiment.

It would not make sense to inject something like Angular or React as part of
test code and would be detrimentally regressive to inject Angular or React
targeted logic over an existing framework application without a more thorough
consideration for second and third order consequences. An experiment is meant
to be something that is created with the least possible labor since its not
production code and short lived.

That said the most desirable approach was to manipulate the DOM directly since
this achieved the fastest execution, provided the smallest risk/footprint, and
was fastest to QA for regression.

\---

In hindsight we learned a couple of things from A/B testing.

* In a page with a lot of asynchronously loading content everything can be precisely altered before the user can notice it. The more precise form of delay were recursive setTimeouts where the interval delay could be manually adjusted to the millisecond and there was never interval overlap. This took practice to know when and where to increase the interval rate without impacting the performance of other logic already in the page.

* The tests did not often reflect the actual business results compared to the production code written later. We found the test logic, even though it was just hacky throwaway code, was generally less defective and faster executing than the more thoroughly tested production code and so performed better than the actual results from the formally released code.

~~~
dahart
> A/B tests are a form of white hat hacking where code is injected into a page

No. The idea of A/B testing does not require DOM manipulation or code
"injection" after the fact on an already rendered page. I don't know about
your A/B tests, but A/B tests in general are site experiments you run on your
users/customers -- the idea does not in general involve code injection, or say
_anything_ about the implementation. I have built A/B tests in React myself,
and there is simply zero technical or performance issues with doing so. You
render one thing for some people, and a different thing for other people, and
measure their reactions.

It might not make sense to use React or Angular for _you_ , for _your_
particular site design, but there is nothing wrong with implementing A/B
testing using React in general.

There's nothing wrong with using JQuery either, if you want direct DOM
manipulation. It would be worth studying _why_ your previous A/B tests were
slow, because it can uncover some knowledge about JQuery. There are bad
practices in JQuery, there are ways to do things really slowly. There are also
ways to fix it when it goes slow, and learning those things might be overall a
lot more efficient than resorting to pure JS DOM manipulation.

~~~
austincheney
> No. The idea of A/B testing does not require DOM manipulation or code
> "injection".

We were using Adobe's Test and Target (Omniture) application for launching and
measuring our tests. It works via code injection.

~~~
dahart
Yeah, that makes sense. The specifics of what you're doing certainly will
drive what the implementation looks like. It makes sense that using Omniture
for tests means that pure JS DOM manipulation is the best way forward. This
detail is actually incredibly important to your story, and so I think it's
easier than not to draw the wrong conclusion from the story because that
important detail was left out. Omniture testing might be something a lot of
candidates aren't exactly clamboring to spend their time doing. Certainly,
with an A/B testing job I would be hoping and aspiring to learn more about
things like site UX, maybe some data science, do HTML & JS that is relevant to
the business team, and be involved in the production site's implementation and
design, etc. I would personally be less excited about using an older legacy
testing framework that requires low level DOM hacking, especially if it seemed
separated from the core dev team. How do you implement the design that wins?
Does the A/B test writer's version get put into production, or does someone
else take the code injection and translate it into HTML?

------
caseymarquis
I recently built a small side project in vanilla js for fun. I just didn't
want to break out webpack and waste an hour getting it set up.

I got pretty far, did all the design. I wanted to run a client side simulation
in javascript though, and found I needed to host a local server as chrome
refused to read modules from a file due to CORS permissions (running chrome
with the usual arguments didn't fix it).

At this point, since I needed an outside piece of software to run things
anyway, I figured I might as well switch to webpack dev-server and get the
whole modern frontend ecosystem. I then quickly started replacing my home
grown dom syncing with vuejs, and snowballed from there.

I definitely learned a couple things, so time well spent, but I'm also going
straight to webpack next time. I know it'll only take a few hours before I
start hitting the limits of what vanilla js can do, and while reinventing the
wheel was fun and educational, it didn't result in a better wheel.

~~~
Kwantuum
Alternatively, you can use a simple web-server without needing all of webpack:

using npx (included with npm):

    
    
        npx serve .
    

using the php CLI:

    
    
        php -S localhost:5000 -t .
    

You weren't hitting the limits of vanilla JS, you were hitting the limit of
reading files directly from disk instead of through a web server.

~~~
staz
or in python 2 (should be on installed by default on most distro):

    
    
       python -m SimpleHTTPServer
    

or python3 :

    
    
        python -m http.server

~~~
sjf
Seriously, the poster is going to have to host their files somewhere
eventually if they intend anyone else to ever see it. I can't believe they
rewrote all their JS because they were forced to access over
[http://](http://) instead of file://. This seems nonsensical.

------
turnipla
Love the website, too bad it doesn't use nor mention the new and much improved
DOM APIs.

This swap function is just `a.replaceWith(c, d, e, …)` in DOM4

[https://htmldom.dev/swap-two-nodes](https://htmldom.dev/swap-two-nodes)

If you haven't seen this before, I highly suggest looking into it.

[https://github.com/WebReflection/dom4](https://github.com/WebReflection/dom4)
(I can't find any articles about DOM 4, so this polyfill’s readme will have to
do)

------
bfred_it
I would never recommend copy-pasting this code into your project:

[https://htmldom.dev/copy-text-to-the-clipboard](https://htmldom.dev/copy-
text-to-the-clipboard)

I get "trying to stay vanilla", but any reasonably-common snippet should
either be installed from npm or published there.

For this specific issue there's a module named almost exactly the same and it
restores the previous selection and focus as well:
[https://github.com/sindresorhus/copy-text-to-
clipboard/blob/...](https://github.com/sindresorhus/copy-text-to-
clipboard/blob/master/index.js)

This is the point of published modules: your code isn't stuck into the version
someone wrote in 10 minutes 5 years ago.

~~~
kllrnohj
> I get "trying to stay vanilla", but any reasonably-common snippet should
> either be installed from npm or published there.

And that's how you end up with the joke that was left-pad and the broken
internet that resulted when the author yanked it.

Dependencies represent a real risk to your product. If it is actually a simple
snippet, you _shouldn 't_ take that as an NPM dependency - the risk/reward
ratio is just way out of whack with that.

~~~
AgentME
NPM disallowed un-publishing modules within a few days of that incident. It's
not a thing that happens any more. Also, NPM for years has defaulted to
creating lockfiles with all the specific versions of dependencies pinned, so
even if a dependency gets updated to have a bug, you will stay on the
currently-pinned version unless you specifically change that.

~~~
kllrnohj
> It's not a thing that happens any more

Except it literally happened again 2 years after the left-pad incident:

[https://status.npmjs.org/incidents/41zfb8qpvrdj](https://status.npmjs.org/incidents/41zfb8qpvrdj)
[https://github.com/facebook/create-react-
app/issues/3701](https://github.com/facebook/create-react-app/issues/3701)
[https://github.com/angular/angular-
cli/issues/9113](https://github.com/angular/angular-cli/issues/9113)

But anyway whether or not the module is un-published doesn't really matter.
The module could also just become malicious. Ownership changes, quality of
code changes, etc... If you're pinning with lockfiles you're basically back to
copy/pasting or checking in a clone of an upstream repo - the maintenance
burden shifts back to you at that point. You still then have to manually go
update, and remember to do that, or you become just as easily obsolete as the
copy/pasted snippet.

------
cousin_it
Nice collection of recipes! Just a few quibbles about the website design:

    
    
        * The back and forward buttons lose scroll position.
        * Visited links look the same as non-visited.
        * In each recipe, top 70% of the screen is headers and whitespace, bottom 30% is content (on my laptop).

~~~
thanatropism

         * The text on this kind of code block is annoying to read even on a 15" laptop with only a slightly enlarged font.

------
krossitalk
This is a really great set of demos! The resizable table columns really irks
me because I spent so long trying to make something similar and it ended up
being hundreds of lines longer.

------
michaelbuckbee
This is nice - it reminds me of the VanillaJS "framework" site -
[http://vanilla-js.com/](http://vanilla-js.com/)

------
emilfihlman
Pretty good! My only wish is that the site would be like
[http://youmightnotneedjquery.com/](http://youmightnotneedjquery.com/), so
that the content would be viewable just by clicking the heading and having new
space for it, perhaps in a fixed window, instead of separate pages.

------
chpmrc
Ironically that website is built in React.

------
jagged-chisel
Are there any starter tutorials that would build from vanilla JaveScript,
implementing solutions to developer problems, then demonstrating how one might
use an existing, well-exercised framework to solve those problems? Every time
I go try to learn about a framework from the project web site, they assume a
tremendous amount of context.

Tangentially, my most recent frustration: I wanted to try a couple frameworks
together (they had no overlap in functionality - not like trying to use React
and Vue together), and they _both_ came with CLI tools to initialize an empty
project and complained when it wasn't empty. They both had different opinions
about how to structure project directories, and neither explained in an
obvious place how else one might get started.

~~~
gen220
It's a difficult place to start from, because a lot of react tutorials are out
of date, misleading, shallow, or deep in useless ways.

I think most people learn these frameworks by being put to work on a mature
code base with established patterns, that already uses a set of frameworks. At
first, you kind of don't understand the control flow, but you get better week
over week from there. Over time, you are bootstraping your own opinions by
asking questions and learning hands-on.

Eventually, you can start a project from scratch including the minimal
dependencies yourself, as you learn what's _actually_ useful, vs what's "the
same interface, but dressed for business".

That being said, I'd recommend getting started with `create-react-app`, and
following some of the tutorials. I'd then recommend jumping into hooks
([https://reactjs.org/docs/hooks-intro.html](https://reactjs.org/docs/hooks-
intro.html)) as soon as possible, unless you have to maintain an older
codebase that uses classes, because in "modern" react code, you're almost
never using classes any more, and that reality bomb is not typically dropped
on you in most react tutorials.

------
evo_9
I started to look into going vanilla JS for a side project and ended up going
with Svelte instead. Worth checking out.

[https://svelte.dev/blog/svelte-3-rethinking-
reactivity](https://svelte.dev/blog/svelte-3-rethinking-reactivity)

~~~
alharith
Svelte is a compiler for vanilla JS with no runtime like react has, so I guess
in a way you are writing vanilla JS?

~~~
evo_9
Pretty much the best of both worlds. It's a pleasure to work with and the tool
chaining isn't quite as overwhelming.

------
miguelmota
It's always worth learning a level lower from what you do, so if you write
frontend UIs with React it's worth learning how DOM manipulation works with
vanilla JS to understand the intricacies and appreciate what the library
abstracts for you.

If you start writing a site in vanilla JS you'll eventually end up writing
your own UI library basically reinventing the wheel which is fine as a
learning experience and personal projects but maybe not the best choice if
you're working on a large scale project with many developers since UI
libraries and frameworks provide a common set of patterns as convention to
follow that makes it easier for everybody to be on the same page.

------
40four
Framework debates aside, if you’re looking to do something in pure JavaScript
this looks like a great resource! Bookmarked :)

------
stasgavrylov
Great resource. I'm wondering whether the examples are your own or copied from
across the web?

I just wanted to point out that some of them are a bit outdated, and I belive
it'd be nice to maintain this list as a reference with modern approaches.

For example, there's no need to use `appendChild`, because DOM today has a
more versatile `append` method.

And `[].forEach.call(cols, function(col) {...}` would look much better and
more declarative as `for (const col of cols) { ... }`.

These are just first 2 examples that I noticed.

~~~
drdec
Your proposed changes are not supported in IE 11. The snippets are advertised
as IE 11+ compatible on the landing page.

~~~
stasgavrylov
You're correct, but let/const don't have full support in IE11 either. I
understand that people are still supporting IE, but still, this website could
stay relevant longer if the examples were written in ESNext.

------
kennydude
One of the issues here is that the examples don't add any accessibility hints
at all. We really should be encouraging people to add as many as possible!

------
Kiro
If anything this reminds me why I'm using React. Having to manually add and
remove children, classes or anything dynamic is just a pain.

------
fourier_mode
Slightly unrelated: I am a complete beginner in Javascript, and I was trying
it out for a small web-based UI. I was surprised how importing one js into
another was non-intuitive. One would need to import all the js's into the main
HTML. Feel free to correct me if I am abusing it.

------
jborichevskiy
Meta-proposition: why can't I tell Google to weigh results from this (or some
arbitrary site) higher after I have confirmed its usefulness? Searching
through JS docs is a nightmare filled with outdated libraries and scummy SEO
articles... so hard to filter through the noise.

~~~
hnrodey
filtering results by domain has been around for many years.

site:htmldom.dev search terms here

~~~
jborichevskiy
Yes of course, but that would involve managing a list of resources and sites.
I suppose one master list would be ok across a range of topics but still seems
a little cumbersome. Maybe could be built as an extension.

------
Waterluvian
Interesting how the list doesn't begin with use of querySelector or
getElementById.

I know these sites are made by experts who aren't necessarily thinking about
beginners, but a foundation, even a small one, is super valuable.

~~~
hk__2
The list is in alphabetical order, so “Select an element or list of elements”
is down with the other S’s: [https://htmldom.dev/select-an-element-or-list-of-
elements](https://htmldom.dev/select-an-element-or-list-of-elements)

~~~
emilfihlman
That's a big oversight, the list should be in the order of learning.

------
z3t4
The trick to manage the DOM with vanilla HTML is to _not_ use HTML! Then
abstract code into functions. The advantage with modern JS frameworks is that
they make it easier to handle state, and state handling is usually very hard.
The trick to state handling in JavaScript is to make use of closures, to
prevent the anti-pattern of global state where you don't know which functions
change what state. The only function allowed to change the state should be
function that created the element! This can be achieved with event listeners
that listens for messages from the server.

------
edroche
This is such a wonderful resource, I wish we had it when first building our
app, which uses no frameworks or libs. We do use TypeScript to generate it,
hard to pass up the benefits and syntax it provides.

------
ericmcer
Js Frameworks are built on top of vanilla JS, so if you build an application
of any complexity you will eventually start to abstract functionality until
you have your own (probably bad) framework.

------
baristaGeek
Ahh thanks. A lot of times you use these fancy frameworks and don't know
what's going on at a lower level. Understanding this makes you understand the
fancy frameworks faster.

------
nojvek
I love this. It doesn't matter what framework you use, having to raw dom
manipulation is eventually a task for any seasoned frontend engineer.
Understanding the dom api is absolutely essential, when performance is
paramount. Resizing tables, drag/drop, e.t.c any advanced interaction will
need control of raw dom. Thanks for writing the little recipes.

I'm not dissing Frameworks. They are a tool that help you with certain kinds
of problems. Any crafts(wo)man, should know their tools well.

------
adrianhel
DOM diffing is great for most stuff. When you need anything other than
"Replace this with that and don't defocus my input fields", DOM manipulations
are great. Drag'n'drop is a great example of this.

There is a lot of potential for the imperative APIs for this though. I even
made a proposal:

[https://github.com/adrianhelvik/proposal-move-
events](https://github.com/adrianhelvik/proposal-move-events)

------
Kiro
I think everyone should know how the DOM works under the hood but the HN hate
for frameworks and love for vanilla JavaScript is just unbelievable. As soon
as you venture past small JavaScript sprinkle you will regret using vanilla.
It feels like a made-up opinion by people who are actually not developing
front-end JavaScript seriously. The DOM API is simply unfit for real web apps
without a proper framework on top.

~~~
nepeckman
Agreed. The only way vanilla JS scales to a large codebase is through serious
discipline and internal tools, essentially creating an ad hoc, poorly
specified, home grown framework. Even the web components standard is
insufficient without abstraction layers on top.

~~~
krapp
Not all codebases are large, and not every site is, or needs to be, enterprise
scale. I think HN sometimes forgets that there's an entire web outside of
FAANG+ and startup culture that doesn't care about any of that.

~~~
Kiro
I don't think you need to be enterprise scale to justify using a front-end
framework. Anything above trivial complexity is enough and it will give you
headroom to scale as a bonus. I think a more common mistake is to use a
framework when you could just as well render it on the server with the same
result and being simpler at the same time.

But when you do need to create a dynamic web app, you should definitely use a
framework. Using vanilla will just result in you creating your own half-baked
framework anyway.

------
akrymski
There's a large range of approaches between a heavy framework like React and
vanilla DOM manipulations. jQuery is one such popular solution, and I don't
see why such helpers should be completely avoided. Another (full disclosure:
I'm the author) is:
[http://techlayer.com/espresso.js/](http://techlayer.com/espresso.js/)

------
maggit
I recently did a write-up of my experience with writing maintainable code with
vanilla JS: [https://magnushoff.com/blog/dependency-free-
javascript/](https://magnushoff.com/blog/dependency-free-javascript/)

I am a huge fan of React for the maintainability of the resulting code, and
this was my attempt to regain some of that without the dependency.

------
donohoe
I'd be interested to see if other people have similar go-to vanilla JS? If so,
can you share a link here?

This one is mine:

[https://github.com/donohoe/content/blob/master/posts/javascr...](https://github.com/donohoe/content/blob/master/posts/javascript-
returns.md)

(I follow basic ES6 syntax but easy to switch as needed)

~~~
tyingq
A vanilla JS replacement for jQuery's ajax functionality, that worked on older
browsers, would be welcome.

Edit: To clarify, a drop in replacement is what I was looking for.

~~~
untog
For me the Fetch API is basically that:

[https://developer.mozilla.org/en-
US/docs/Web/API/Fetch_API](https://developer.mozilla.org/en-
US/docs/Web/API/Fetch_API)

    
    
        fetch("http://www.example.com").then(res => res.json()).then(json => {})
    

Only big downside is no IE11 support but thankfully I don't have to worry
about that so much these days.

~~~
leetrout
It still doesn't go POST in a nice way like the jQuery API does BUT it is not
worth bringing jQuery to the page just for making requests with slightly nicer
syntax.

~~~
untog
What’s not nice about POST?

    
    
        fetch(url, {
          method: “POST”,
          body: “a body”
        })

------
TheRealPomax
For point 11, checking the bbox can be unreliable. JS got an Intersection
Observer API a while back - [https://developer.mozilla.org/en-
US/docs/Web/API/Intersectio...](https://developer.mozilla.org/en-
US/docs/Web/API/Intersection_Observer_API)

------
woranl
Framework comes and goes. What’s cool today will become obsolete many years
later. Vanilla code has less dependencies.

------
cfv
Pretty cool!

One thing that would massively improve this is if they were written as
singular standalone blocks instead of sparse collections of snippets; I'd like
to be able to grab, say, "make an element draggable" and toss it on my
codebase as an isolated behavior.

------
jnet
ele.classList.toggle('class-name');

That seems really useful, and I had no idea it existed.

------
bin0
This kind of thing sounds great on personal projects, but doesn't scale. Like
many abstractions, frameworks' biggest benefit is (arguably) making it easier
for teams to work together.

------
divbzero
Excellent. Reminds me of You Might Not Need jQuery [1] from awhile back.

[1]: [http://youmightnotneedjquery.com/](http://youmightnotneedjquery.com/)

~~~
pxtail
Which is quite funny as it serves as very good demonstration why one _should_
use jQuery: most of presented examples are 10 times more longer when it comes
to code amount or alternatively there is some weird oneliner. All of that for
saving 30KB of battle tested cross browser code.

~~~
hombre_fatal
Though note that it doesn't demo anything that only works in IE11+. It doesn't
even demo window.fetch().

It's a pretty poor reference for most people. For example, you have no reason
to be defaulting to XMLHttpRequest for http requests.

------
mattlondon
Similar site from much longer ago, but with less content:

[http://standardjavascript.info/](http://standardjavascript.info/)

------
stevedekorte
This is a great resource. I've had to dig through a lot of StackOverflow
threads to figure these out. Great to have lots of current answers in one
place.

------
wilsonbright
Great resource. Well built and it is going to helpful to many.

------
henriquez
Nice work. I was looking for something just like this!

------
niyazpk
>> "for modern browsers and IE 11+"

Ouch!

~~~
jjcm
I feel like Safari should be included in there as well. Safari is the new IE,
they're so slow in adopting new specs. With IE having moved to chromium and
Firefox having solid contributions to the spec and always being on the
bleeding edge, we were bound to see the it be the one fall behind given
Apple's slower cadence, but I've been amazed at how much of a blocker it's
been.

------
redis_mlc
I'm a vanilla-js guy.

That cookbook is pretty good.

If anybody has a good way of doing a password dialog in vanilla-js, please
post a link.

It's the one thing I've encountered where I wish I had used a framework.

~~~
101008
Sorry, what's a password dialog?

~~~
omgwtfbbqhihihi
A dialog box that prompts for your password. Never seen one?

~~~
satvikpendem
Like <input type="password">? Or something more complex?

~~~
ken
That’s a password _field_. Now just put it in a <dialog>.

~~~
satvikpendem
What's the problem exactly? I assume you looked into putting that input
element inside a dialog element and it didn't work, is that the issue?

~~~
redis_mlc
dialog is not supported on Firefox and Safari without a polyfill.

------
hk__2
Ironically, the site itself uses ~100ko of gzip’d JS.

~~~
zeusly
And is built in react. It's about choosing the right tool for the job.

~~~
hk__2
> And is built in react. It's about choosing the right tool for the job.

React is useless here. Try browsing the website without JS and notice how
litterally nothing changes.

The only things that need JS are the light filter at the top and the fast
navigation using body/head swapping + pushState, none of which require React.

~~~
dubcanada
On the frontend, yes. But it seems that it does server side compiling.

So basically the frontend JS is so the backend can produce HTML.

Rather weird way of looking at it.

------
guggle
That's great ! Very useful.

------
baybal2
Protip: [https://developer.mozilla.org/en-
US/docs/Web/API/XSLTProcess...](https://developer.mozilla.org/en-
US/docs/Web/API/XSLTProcessor)

------
KaoruAoiShiho
This is useful for some devs in some situations, but let's not go overboard.
Teaching newbies to venerate vanilla is almost educational malpractice.

~~~
bob1029
Teaching newbies that they can gloss over fundamental details with some extra
NPM commands is certainly educational malpractice IMO.

