An Intro to JavaScript
The Muscles of the Web
JavaScript is the language/format for adding interactivity to a web page—based on actions or
-
JavaScript: Adding interactivity – MDN
There areliterally millions of sites about JS, but let’s start with MDN. -
JavaScript – MDN
Another MDN into. -
Highest-scored JavaScript Questions – Stack Overflow
It’s like Reddit for code! (Always check the year on answers. Some areold !) -
The Modern Javascript Tutorial
This reference goes very advanced/in-depth. -
Eloquent JavaScript
Also goes deep.
Going back to a very early analogy, JavaScript is the .js .
JavaScript was first created by Brendan Eich over just
The idea was to make something that Web designers, people who may or may not have much programming training, could use to add a little bit of animation or a little bit of smarts to their Web forms and their Web pages.
Like HTML/CSS, JavaScript was a malleable,
Remember that now the tendrils of JavaScript are almost everywhere—running headless on servers, rendering whole sites, talking to hardware, processing NASA images, and so on. It’s web technologies, all the way down.
Libraries / Frameworks vs. Plain / Vanilla JS
You’ll often hear folks talk about
Things like
When you write JS without libraries, it is called
The language has evolved so much that we can do a lot, here, and this is where we’ll start. And while JS does many things, we’ll first just use it in the most simple way—to make our web pages more interactive.
Where Does JS Live?
Very much like CSS, JavaScript code can live in several places:
Inline as attributes on elements- Inside
<script>elements within HTML documents - As separate/external
.jsfiles(the right way) , viasrc=""attributes
1. Inline Event Handlers
JS was first added directly in attributes in HTML tags, just like CSS—but attached and “listening” for specific events:
<button onclick="alert('The button was clicked!');">Click here!</button>
Note the single quotes when nested/inside doubles!
This works for very, very simple things, but—for many of the same reasons as inline CSS—is brittle and doesn’t scale with complexity, or across multiple pages. Try writing a whole, elaborate function in there, let alone an entire framework! No good.
2. Wrapped in <script> Tags
And again like CSS, JavaScript can be enclosed in its own special tag, the <script> element.
-
<script>The Script element – MDN
More minutia on using these in-HTML elements. -
Document:
querySelector()method – MDN
This is how you find/specify/target HTML elements in JS. -
EventTarget:
addEventListener()method – MDN
And then listen forevents happening on them—onclickis a shorthand.
These are also often, somewhat confusingly, called
Anything inside the tag should be written in JavaScript syntax and will be executed </body>, so they can “see” the whole page before!
Since this script isn’t directly querySelector, and then addEventListener on it, click event:
// comment syntax for JS! And we had to add cursor: pointer; for the button in our CSS, to indicate it is actionable. Mind your affordances!
3. Separate / External .js Files
By far the most robust, flexible way to include JavaScript is externally—again, like CSS. The difference here is that instead of a <link> element, we still use a (now empty) <script> tag, with the addition of a defer and src="filename.js" attribute:
deferproperty – MDN
Needed for<head>scripts to “see” your HTML!
<script defer src="script.js"></script>
Michael has always disliked this empty-tag syntax; what can you do.
This will still run when the document gets to the <script> (and in its place/order) as before—but the additional defer attribute allows it to “see” the HTML (not yet loaded) below it. Without this attribute, it doesn’t know about the rest of the page!
Prior to (the relatively recent) defer, you could wrap logic in a DOMContentLoaded or load event listener. You’ll likely see this is older examples/suggestions online!
We can then move the script up into our <head>, along with our other external files:
It’s the same exact JavaScript and behavior as the inline example above—but now moved over into a nice, separate, JS-syntax-highlighted file that can be re-used across pages.
The most resilient, easiest way to use JavaScript is in a separate file—just like CSS, for all the same reasons.
Oh Also, <noscript>
Some folks block/disable JavaScript—for performance or accessibility reasons, or to hide advertising/annoyances, and so on. This is less and less common these days, since so many sites <noscript> tag to show content only when scripting is turned off:
<noscript class="warning">
Our site uses JavaScript for some of its functionality, which is disabled in your browser.
</noscript>
You can test these by disabling JavaScript in your DevTools.
Adding / Removing a Class
Okay, time for a more practical example: probably the most common thing you will use JS for—especially as we’re starting out—is simply to add or remove (
-
Storing the information you need—Variables – MDN
Variables are always going to make your life easier. -
Element:
classListproperty – MDN
Controls the CSS classes on an HTML element.
Like with our earlier transition will smooth out the change. Keep in mind here that the JS doesn’t (and shouldn’t/needn’t) do anything visual, itself! That is still the domain of our styles.
We’ll again use querySelector to target our elements—but here we’ll store them as
Then using our variables, we’ll again add an addEventListener to listen for a click, now modifying the classList (CSS classes) of a
JavaScript’s querySelector takes classList can be modified on any element in your HTML (or sometimes, even just on document.body itself)! You can also specifically use classList.add and classList.remove, if you don’t want or need to separate the on-and-off behavior from classList.toggle !
You can do many, many things with this basic “toggle a class” JS! It’s the basis for much of the interactivity you see online.
Opening a Modal
You might also want to use JavaScript to “open” a modal <dialog> element—which you might use for a menu, an overlay, or a lightbox. (In the software sense, a <dialog> before they can do anything else.)
-
<dialog>: The Dialog element – MDN
You used to have to write alot more JS for these! -
::backdrop– MDN
Style the overlays behind them.
You could (and used to) do this by adding/removing classes—but this newer element uses JS to toggle an open attribute (akin to <details>/<summary>) for the two states. This approach gives us some nice “free”, built-in behaviors: making the rest of the page inert, adding a ::backdrop pseudo-element, stopping background scrolling (this still needs CSS!), and even listening to Esc for dismissing/closing the modal.
It’s a lot of useful behavior without too much code:
style.css changes to make the dialog appear as we want. This is all a bit hokey, but better than it used to be!
Watching for Scrolling
Another very common, designer-y use for JavaScript is to do something when an element enters or exits the viewport, scrolling into or out of view—like fading, highlighting, or moving something in. Remember, acknowledging and responding to the viewport is always very
-
Intersection Observer API – MDN
Watch for things entering/exiting the viewport. -
if…else– MDN
Conditional logic blocks, “if this then that.”
Again we’ll need two states in our CSS, defined with and without a class. But now we’ll make use of the user’s scrolling—instead of a click event—to toggle the between the two visual states. Our JS still
This used to be IntersectionObserver to watch the element:
if / else statement, an example of conditional logic!
Loops
You will often want to use this on multiple elements—and remember, when in code,
-
Element:
querySelectorAll()method – MDN
Gets multiple elements. -
forEach()– MDN
And “loop” through them.
We can use querySelectorAll to select forEach
rootMargin from the full-viewport default with an inset, so the elements don’t transition immediately.
Some Miscellaneous JS Tips
Alright, that is a lot. Like we’ve been saying—JavaScript is
-
Using
alert(yourVariable)fortelemetry /debugging can quickly be pretty annoying—instead, you can useconsole.log(yourVariable)to show messages in the DevTools console.A quick
console.log('Hello world!')can check if things are plugged in right. The console will also show any JavaScript errors!In other languages, these functions are often, ironically, called
print . -
Search on
Stack Overflow ! (Though it’s… probably on the way out.) Anotherperson has likely had your problem, before.Many people don’t really
know JS (Michael included)… so much as they really know how to find things elsewhere on the internet:Stack Overflow ,Codepen , and so on. -
This brings us back to LLMs,
large language models (“artificial intelligence”)—tools like ChatsGPT, GitHub Copilot, Claude Code, etc.These
can be useful; we use them ourselves. But much likeStack Overflow or any other resource online, you have to know what to look for—and need a level of understanding to do this to, and to discern the value from the noise/code salad.
-
Ignore any examples/suggestions that have lots of dollar signs, like
$("something").else—it means this is jQuery, and so isvery outdated! (And Eric really,really doesn’t like jQuery.) -
You’ll also likely see examples/suggestions that wrap some logic in a
DOMContentLoaded(orload) event listener—which will run the contentsafter the whole page is available, no matter where the<script>element is located in the HTML. But we’ll use the moderndeferattribute to avoid this dance!Old way
<script src="script.js"></script>document.addEventListener('DOMContentLoaded', () => { console.log('Runs after the page is loaded!') })New/better way
<script defer src="script.js"></script>console.log('Runs after the page is loaded!') -
To quickly get recent/modern,
vanilla JavaScript results, instead include “ES 6+ ” in your searches and prompts—this refers to a more recent, easier-to-use syntax. Models often now skew/default towards this, but not always! -
Relatedly, if you see “arrow functions” (with
=>) it is a pretty good sign the answer is relatively recent.Declaring variables with
letandconst(instead of the oldervar) is another good sign. -
Like HTML/CSS, JS does not
really care about whitespace or tabbing. Use them for your own clarity! -
But it
is case-sensitive! SothisandThisarenot the same. (The most common JS convention iscamelCase .) -
Many new-to-JS problems are caused by unclosed blocks and groupings. Akin to HTML’s
<> </>and CSS’s{ }, always mind your matching{ }and( )in JS! -
You’ll also see a lot of semicolons
;but secretly you (almost never) actually need them! Declutter your code.
Any application that
can be written in JavaScript,will eventually be written in JavaScript.