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!');
}
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');