Indie Web Guide
Indie Web Guide - Basic JavaScript
Let's learn to manipulate HTML/CSS and add functionality to your sites with JavaScript!
If you are new to HTML/CSS, please refer to the Introduction Guide before continuing. I also recommend reading the Basic HTML & Basic CSS guides as well.
Basic JavaScript
JavaScript is a pretty big topic, so I mainly want to cover the core concepts in this basic guide.
Where HTML defines the structure and CSS defines the visual design, JavaScript handles the interaction logic to manipulate the other two. Yes, you can control both HTML and CSS via JavaScript.
If you have a button you'd like to display a message to the user or create an effect that tracks the mouse, you'd need to reach for JavaScript, or other web-friendly functional programming language.
Similar to CSS, JavaScript can be located with the HTML, either as a <script> tag at the bottom of the <body> tag with raw JavaScript:
<body>
<!-- Other HTML elements go above this -->
<script>
// JavaScript goes here
</script>
</body>
or with a src pointing to the .js file.
<body>
<!-- Other HTML elements go above this -->
<script>
// JavaScript goes here
</script>
</body>
<body>
<!-- Other HTML elements go above this -->
<script src="index.js"></script>
</body>
There is a third option, which is to put the <script> tag (either the raw or src version) in the head, but you must use <script defer> to tell it to load after everything else to ensure that it works properly.
<head>
<script defer>
// JavaScript goes here
</script>
</head>
Once you have a method of getting the script into your HTML, you can test if it is working properly by doing something like:
document.body.innerText = "Hello world!";
This should remove all other page content and replace it with the string "Hello world!". In JavaScript, a string (plaint text) is denoted by wrapping the text in double-quotes (") or single-quotes (').
In the example, we successfully targeted the HTML document (always targets the HTML document it is linked to), targeted the body element by chaining ., then changed the innerText equal to a new value.
To break this down further, as it is pretty basic in terms of what you'll be learning, JavaScript uses objects pretty often. You don't need to worry about objects right now, but just know that you can access object values with dot notation, or chaining, which is a variable or identifier, followed by a period, followed by another identifier. This pattern can repeat nearly indefinitely, so you can go deeper into the object by just adding onto the chain, which is how we got down to innerText.
document is an object that contains specific values that it finds within your HTML document, which is why it is very important to structure your apps with the typical boilerplate. The document provides direct access to basic elements like <body> via document.body and <head> via, you guessed it, document.head.
Any time you need to target something in your HTML, you'll likely need the document object to find it.
So, we know we can get the body and head and a few other basic/expected elements, but how can we get anything else?
Similar to CSS, JavaScript has a method to select all or specific elements. If you wanted to get the <button class="test-button> from the basic CSS guide, you can simply target it the same way using a period to denote a class. As for how you actually initiate the targeting, you can use one of many methods:
getElementByID()- Gets the first element matching the specifiedidvalue.getElementsByClassName()- Gets all elements matching the specifiedclassattribute value.getElementByName()- Gets the first element matching the specifiednameattribute value.getElementsByTagName()- Gets all elements matching the specified tag name.querySelector()orquerySelectorAll()- Selects the first or all elements matching specified CSS selectors.
In practice, to target the button we mentioned, we can use querySelector to get the first (and only) instance of the button.
document.querySelector(".test-button");
Now, as-is you'd have to do any operations on this instance, or repeat it over and over like this:
document.querySelector(".test-button").innerText = "I am a button";
document.querySelector(".test-button").title = "Hover me!";
Trailing semi-colons (
;) are optional, but can give a clear "this is where the line ends" when reading the code.
Which is fine, but you might want to maintain a list of references as variables to keep things cleaner.
In JavaScript, there are a few variable types:
const- This defines a value that will never change (and will throw errors if you try). You must provide a default value.let- This defines a value that is likely to change over time.var- This is a more generic value that may or may not change.
In this case, we don't expect to target another element with the same reference later, so we can use const.
const testButton = document.querySelector(".test-button");
And we can now reuse that variable in place of those other references.
const testButton = document.querySelector(".test-button");
testButton.innerText = "I am a button";
testButton.title = "Hover me!";
Variables can be used to store virtually any type of value:
string- text -var str = "A string.";number- int/float -var num = 4;array- multiple values -var arr = ["string", 5];object- multiple key/value pairs -var obj = {key: "value"};
And, of course, HTML elements, URLs, etc. There are tons of special values in JavaScript, but these are the main ones you'll care about to start with.
Another example is if you wanted to use your site name over and over, but don't really want to have to go change all those values later. You can have a single JavaScript variable that contains your site name:
const siteName = "My Site";
const logoElement = document.querySelector(".site-name");
const footerElement = document.querySelector(".site-name");
logoElement.innerText = siteName;
footerElement.innerText = siteName;
So any time you change the value of siteName, it will change in any place where you've used it as a value for something else.
Now, a practical example might require more advanced logic, but for a simple solution, you could create a <span class="site-name"> or something to replace specific chunks of text, if you like.
So far, we've covered a couple of basic operations, like swapping the inner text of an element, or setting a title attribute.
Still writing this, enjoy the preview!