Web Platform

Javascript

Doing something

This section briefly outlines a few techniques for doing something in Javascript. How to reference elements in the DOM from Javascript, responding to interaction, changing the contents of an element and hiding or showing elements. A few "starter" techniques that subsequent sections will expand on.

Handle an interaction

Most elements have a few basic interaction events which we can 'listen' to, and take action from. Events have a name, such as: click, touchstart, mousedown and so forth.

The basic format is addEventListener(eventName, func), where eventName is the string name of the event, and func is a function reference to the code to run when the event fires.

Starting from the starter skeleton HTML, let's put a BUTTON element in the HTML, and listen for it when it is clicked.

In the HTML file, add a button with an id we'll use to reference the button in Javascript:

<button id="activateButton">Activate</button>

In your JS file:

// Runs when the script is loaded
if (document.readyState != 'loading') {
  onDocumentReady(); // Document is already loaded, call onDoumentReady
} else {
  document.addEventListener('DOMContentLoaded', onDocumentReady); // Not loaded yet, so listen for event and then call function
}

// Runs when the document is ready
function onDocumentReady() {
  // Get the button element by its id
  const el = document.getElementById('activateButton');

  // Wire up the 'click' event to the function onButtonClicked
  el.addEventListener('click', onButtonClicked);
}

// Runs when the button is clicked
const onButtonClicked = function(e) =>{
  console.log('Clicked!');
}

See a live demo

The id of the button, as defined in our HTML, is used to locate the element in code with document.getElementById(). Once we have the element, we can wire up the click event to the onButtonClicked function. This means that whenever a 'click' event happens on the button (or one of its descendant elements), the onButtonClicked function will be executed.

Note that the event text is a string, and thus enclosed in '' marks, while the function name must match a defined function. The function name can be whatever you like, you just have to make sure it exists (you'll see an error in the console otherwise).

If you get the event name wrong, eg supplying clickk instead of click you won't get any errors, but since clickk never happens, your function will never be called.

Event handlers can be removed in a similar way:

el.removeEventListener(eventName, func);

For example, if you want the button to only work a single time:

// Runs when the document is ready
function onDocumentReady() {
  const el = document.getElementById('activateButton');
  el.addEventListener('click', onButtonClicked);
}

// Runs when the button is clicked for the first time
const onButtonClicked = (e) => {
  console.log('Clicked!');
  e.target.removeEventListener('click', onButtonClicked);
}

Work with multiple elements

Referring to elements by id is fine, but it's often we want to do something with a bunch of elements that match a selector or have a particular class.

For example to toggle the 'hidden' class of every element which also has the 'detail' class:

const details = document.getElementsByClassName('detail');
for (const el of details) {
  el.classList.toggle('hidden');
}

If you have some accompanying CSS, you can make elements show or hide:

.hidden {
  display: none;
}

Instead of using getElementsByClassName, we could also use a selector. Selectors are a more powerful way of finding elements within a document, going far beyond simple class names.

The following snippet will add the class 'hidden' to every element which matches the selector (in this case, every BUTTON element contained any NAV element).

var buttons = document.querySelectorAll('nav button');
for (var el of buttons) {
  el.classList.add('hidden');
  // classes can be removed with .remove('nameOfClass') as well
}

Toggling, adding or removing classes is an ideal way to manipulate appearance. With CSS you can use transitions and such to animate property changes as classes are applied or removed.

With selectors, you can also see the usefulness of structuring your HTML document in a semantically sound way. It makes your possibilities of referring to things much more easier.

Changing contents

Once you have a reference to an element, change its contents as follows:

el.innerHTML = 'Something <b>different</b>'; // Assign HTML
el.innerText = 'Something different';        // Assign text

Hiding/showing

Ideally you hide/show something by adding/removing (or toggling) a class which has display: none set.

CSS:

.hidden {
  display: none;
}

HTML:

<button id="button1" class="hidden">I'm hidden by default</button>

<button id="button2">I'm not hidden</button>

Javascript:

// Show the first button
document.getElementById('button1').classList.remove('hidden');
// Hide the second button
document.getElementById('button2').classList.add('hidden');

Live demo

Read more