Javascript tidbits

This tutorial is an introduction to javascript and how to use it on your website. I'm an intermediate coder myself, so the tips are aimed more towards beginners!

Without getting too into the language itself, the tutorial will focus on how to link a script to make it work on your page and showcase a few common useful functionalities that are possible to achieve with beginner-level JS, HTML and CSS code.

It's quite a long one, be warned :)

❓ Introduction: what's javascript and how do i use it?

Javascript is a scripting language used to define client-side scripts on websites. On static sites - like those hosted on Neocities, JS is often used for more complex animations, saving user settings, or dynamic content/style changes. For example, here's a button that changes its color using javascript!

Defining a client-side script is done using the HTML <script> tag. Inside this tag you can define variables, functions, and basically everything javascript. Below is the code used for the color-changing button.

<div>
    <button id="btn" onclick="changeColor()">Click me!</button>
</div>
<script>
    function changeColor() {
        const button = document.getElementById("btn"); // find the button element
        button.style.backgroundColor = "rgb(80, 160, 110)"; // change button color
    }
</script>

The function changeColor() - when called/triggered - looks for an element with a specified id and modifies its style. The id attribute is basically just a unique name for an element. The button itself has the specified id and uses its onclick attribute to call this function when clicked... and that's it!

The above is an example of a script tag containing the code itself. The other way is to keep the function in a separate js file, and link it in your html file like this:

<div>
    <button id="btn" onclick="changeColor()">Click me!</button>
</div>
<script src="enter path to your .js file"></script>

Keep in mind that here, the code from the previous script tag should be stored in a JS file in your website directory. It's mainly just preference whether you keep all the code in your html or in separate files, but having a separate javascript folder keeps things cleaner and makes it easier to reuse the same code on multiple pages!

With the introduction to how scripts work done, we can move on to presenting a few useful ways javascript can help you enhance your website :)

📍 Inserting content

Inserting content with javascript is useful when you want to have the same element appear on multiple pages (a navigation bar, for example) - or if you just want to have an element's contents be updatable without having to change the HTML every time.

Here's a quick way to add a navigation bar to your website:

// navigation.js file

// define what you want the contents of the navigation box to be
let navigationContent = `
    <a href="/page1.html">Page 1</a>
    <a href="/page2.html">Page 2</a>
    <a href="/page3.html">Page 3</a>
`;

// this part will trigger once the page loads
document.addEventListener('DOMContentLoaded', function() {

    // check for an element with the "nav" id
    if (document.getElementById("nav")) {
        // if the element exists on page, set its contents to the navigationContent variable
        document.getElementById("nav").innerHTML = navigationContent;
    }
});

The above script will search for a 'nav' id and replace whatever content inside of this element with navigationContent. You can link the script in multiple pages, and the navigation box will have the same contents everywhere!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Your html document</title>

    <!-- you can link your script in the <head> tag -->
    <script src="enter path to navigation.js file"></script>

</head>
<body>

    <div id="nav"></div>

    <!-- OR, you can link your script at the bottom of the <body> tag -->
    <script src="enter path to navigation.js file"></script>

</body>
</html>

* Question: Why can the script be linked in 2 diffreent places?
Linking a JS script in the <head> tag means it might be loaded before the rest of the page's elements (html loads elements from top to bottom). Linking a script at the end of the <body> tag means it will be loaded once all page elements have been parsed and loaded.

So, if the js code is looking for a specific id, it might not find one if it is being executed before the html loads the element with this id. This is why it's generally safer to put the scripts at the bottom of your page.

Unless! This code fragment in the js above: document.addEventListener('DOMContentLoaded', function() { ... } means that the code inside will be executed only when the entire page has been parsed. This means that the search for a specific id will start only after every html element is loaded!

So, general rule of thumb: put scripts at the bottom of the page, unless you know what you're doing and/or have implemented safety protocols!

Quote-of-the-day button

The idea behind a quote-of-the-day style element is to periodically change its contents, choosing from a set array. This could be used for fun facts, random featured images, or whatever you want!

In this example, we'll make a button that changes the text of an element on click, like the one below!

Here's the code used:

<p id="quote-display">In this example, we'll make a button that changes the text of an element on click, like the one below!</p>

<div>
    <button onclick="showQuote()" id="quote-button">Change text</button>
</div>

<script> 
    // create an array of quotes to choose from
    // this array can also store html tags (images, links, etc) - surrounded by quotation marks
    const quotes = [
        "I changed this text using JavaScript!",
        "Button clicking is fun :)",
        "Click some more!!!",
        "What's for dessert?",
        "Lorem ipsum dolor sit, amet consectetur adipisicing elit."
    ];

    // the actual function displaying a random quote
    function showQuote() {
        // get a random quote number using javascript's Math object
        const randomIndex = Math.floor(Math.random() * quotes.length);

        // find the display element and insert the random quote
        document.getElementById("quote-display").innerHTML = quotes[randomIndex];
    }
</script>

This function doesn't necessarily have to be triggered with a button. You could make it trigger periodically on a timer, for example. Imagination (and your googling skills) are the limit!

🎨 CSS theme switching

The basic concept of a theme switcher focuses on 2 things: saving the current theme choice in your browser (using javascript), and having separate CSS styles for every color theme.

Here's an example of a theme switcher: use the buttons below to change the colors of the boxes! Note that because the current theme is saved in your browser, the colors will stay the same even if you reload this page!

This code needs HTML, CSS and JS to work, and while you could store it all in one HTML file, I chose to split it into 3 files, for clarity. The code goes like this (it's a bit long, sorry!):

// javascript file or <script> tag in HTML

// list of all available themes
const themes = ['blue', 'green'];

function setColorTheme(theme) {
    // remove all theme classes from the document (for safe switching)
    themes.forEach(item => document.documentElement.classList.remove(item));

    // add the chosen theme class to the document
    document.documentElement.classList.add(theme);

    // save the chosen theme in local storage (stored in your browser)
    localStorage.setItem('color-theme', theme);
}


// get the current chosen theme from local storage
// if local storage doesn't have a saved theme, choose "green" as a default
const currentTheme = localStorage.getItem('color-theme') || 'green';

// set the chosen theme
setColorTheme(currentTheme);

I hope the code comments do their job explaining what's going on in the javascript part of this theme switcher. The general idea is that the information what theme is currently chosen is stored in something called local storage.

Local storage is a way to save data in 'key: value' pairs. The data is stored in the browser with no expiration date, and will not be deleted even if the browser is closed!

The saved theme is added to the document (to the <html> tag) as a class. These theme classes will be targeted by CSS, so when the theme value gets modified, the colors change dynamically! Here's how to save the colors using CSS:

/* CSS file or <style> tag in HTML */

/* default colors, useful if somehow the theme doesn't get set using javascript */
:root {
    --color1: rgb(18, 97, 75);
    --color2: rgb(50, 142, 110);
    --color3: rgb(103, 174, 110);
    --color4: rgb(144, 198, 124);
    --color5: rgb(225, 238, 188);
}

/* css variables for green theme */
.green {
    --color1: rgb(18, 97, 75);
    --color2: rgb(50, 142, 110);
    --color3: rgb(103, 174, 110);
    --color4: rgb(144, 198, 124);
    --color5: rgb(225, 238, 188);
}

/* css variables for blue theme */
.blue {
    --color1: rgb(18, 36, 97);
    --color2: rgb(50, 71, 142);
    --color3: rgb(93, 144, 176);
    --color4: rgb(124, 190, 198);
    --color5: rgb(188, 235, 238);
}

/* general style of the boxes */
#theme-box {
    display: flex;
    flex-direction: row;
    gap: 5px;
    justify-content: center;
    flex-wrap: wrap;
}

#theme-box div {
    width: 100px;
    height: 100px;
    border-radius: 3px;
}

/* each box's background color is a variable, so it can change dynamically */
#theme-box :nth-child(1) {
    background-color: var(--color1);
}

#theme-box :nth-child(2) {
    background-color: var(--color2);
}

#theme-box :nth-child(3) {
    background-color: var(--color3);
}

#theme-box :nth-child(4) {
    background-color: var(--color4);
}

#theme-box :nth-child(5) {
    background-color: var(--color5);
}

The colors are stored in CSS variables in --variable-name: value; format. The classes .green and .blue get their own sets of different colors. I like to specify default colors using :root at the beginning of my style sheet, just in case the javascript doesn't work and the document doesn't have either style class assigned.

Each box gets assigned a background color using just the variable names in a background-color: var(--variable-name); format. By using variables instead of specifying the exact rgb value, the colors can be changed dynamically by changing the variable values themselves.

Finally, this is how it all connects in the HTML file:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Your html document</title>

    <link rel="stylesheet" href="enter path to css file">

    <script src="enter path to javascript file"></script>

</head>
<body>

    <div id="color-theme-buttons">
        <button onclick="setColorTheme('green')">Green Theme</button>
        <button onclick="setColorTheme('blue')">Blue Theme</button>
    </div>

    <div id="theme-box">
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
    </div>

</body>
</html>

In this case, both the CSS file and the JS file are linked in the <head> tag. This is because there's no need for any specific elements of the page to load before the javascript code can be executed.

In fact, executing this JS code before the full page loads eliminates the possibility of the default theme appearing for a short time before the correct theme gets applied.

Finally, the buttons trigger the setColorTheme() function with a specific theme value, and that's it!

✅ Item filtering

Item filtering means showing a specific set of items based on user choice. This is useful for art portfolios, or blog tags for example. For the purposes of this showcase, we'll filter images based on their color.

Here's the showcase, including 2 (of many) ways to implement the filter choice: buttons and a dropdown menu!

Here's the code that makes it work:

// javascript file

function filterImg(filter) {
    // find all elements with this class
    const images = document.querySelectorAll('.img-to-filter');

    // for each image, hide or show it based on their tag values
    // if filter is empty ("") every image will be shown
    images.forEach(image => {
        if (image.getAttribute("tags").includes(filter)) {
            image.style.display = "flex";
        } else {
            image.style.display = "none";
        }
    });
}

The javascript function, when called, searches for every element with the class .img-to-filter. It then goes through every element and decides whether to hide or show it based on its tags attribute.

The tags attribute is just additional data added to an element. You can add however many attributes to an element, and name them however you want, too! You just need to make sure that it's not an attribute already commonly used in html for something else, like href or style.

The HTML is quite simple, if you're already familiar with adding functions to buttons. The dropdown menu requires specific syntax, but it's quite analogous with the button system - when choosing a new option, it calls the filterImg() function with the new value.

<div class="gallery">
    <img class="img-to-filter" src="./_img/javascript/1.jpg" tags="warm">
    <img class="img-to-filter" src="./_img/javascript/2.jpg" tags="warm">
    <img class="img-to-filter" src="./_img/javascript/3.jpg" tags="warm cool">
    <img class="img-to-filter" src="./_img/javascript/4.jpg" tags="cool">
    <img class="img-to-filter" src="./_img/javascript/5.jpg" tags="cool">
</div>

<!-- Buttons -->
<div>
    <button onclick="filterImg('warm')">Show warm hues</button>
    <button onclick="filterImg('')">Show all hues</button>
    <button onclick="filterImg('cool')">Show cool hues</button>
</div>

<!-- Dropdown menu -->
<div>
    <label for="filter">Filter images: </label>
    <select name="filter" id="filter" onchange="filterImg(this.value)">
        <option value="">Show all</option>
        <option value="warm">Warm</option>
        <option value="cool">Cool</option>
    </select>
</div>

<script src="enter path to js file"></script>

Summary

And that's the end! Remember, this tutorial shouldn't be treated as absolute truth, or the best and only way to implement these functionalities. That's just how I make them work based on my experience working on static HTML websites and some classes in uni :)

That being said, I hope there's someone out there who will find this specific type of showcase and explanation useful! If you want to learn more, I highly recommend w3schools for beginner coders. They have solid showcases for a lot of concepts, like collapsibles, which I didn't end up putting here in the end :V

Let me know if you have any problems with the code shown! Feel free to comment if there's anything else you'd like a tutorial on, and maybe I could make a part 2 someday :)

< back