JavaScript Magic 8 Ball with Basic DOM Manipulation

Kelly Lougheed
Feb 14, 2018 · 8 min read
Photo by Igor Ovsyannykov on Unsplash

So you know HTML, but now you want to manipulate the HTML elements on your page with JavaScript. How do you make something happen when you click on a button? How do you get user input from a text input box and then actually do something with it? This tutorial will show you how!

Getting started

Go to glitch.com/~8ball-starter and hit “Remix your own.” This code contains all the HTML and CSS for your Magic 8 Ball, which you can preview by pressing the “Show Live” button.

Click “Show Live” to see the starter…
Your Magic 8 Ball starter!

Right now, the “Shake” button does nothing. You’ll fix that when you write the JavaScript. But you can see that the user is prompted to input a question for the Magic 8 Ball to answer when they press “Shake.”

When you click on index.html in the file list on the left, you’ll see this code inside the body tags:

You will likely recognize many of the tags, such as h1, p, and div. Remember that HTML elements generally consist of a closing and opening tag with content in between (although notice that input is self-closing and one of our p tags is empty).

You may know that the class attribute helps apply CSS styles to particular HTML elements. The related id attribute helps target particular elements more specifically — whereas you can apply a class to many elements, you should only apply an id to one element.

We can also use an element’s id to target it with JavaScript. Let’s do that now.

Grabbing HTML elements with JavaScript

If you want to manipulate an HTML element with JavaScript, you can’t do it directly in the HTML. Although you may have seen JavaScript mixed in with HTML contained in script tags, best practice is to create a separate script.js file for all your JavaScript.

If you click on the script.js file in the file list on the left, you’ll be taken a blank document, ready to be filled with JavaScript.

The first thing we’re going to do is target some of our HTML elements and store them in variables so we can easily access and manipulate them.

JavaScript knows all the HTML in your index.html file as a big object called document (technically, a Document Object Model), and we can use the JavaScript method getElementById to retrieve specific HTML elements by their id.

What elements do I want to target in the HTML? First, I want something to happen when the button is clicked, so I’ll store the button in a variable. Its id is button, so I can store it in a variable with this code:

var tells the computer I’m declaring a variable. Now the whole HTML element of the button is contained in a JavaScript variable called button! This allows me to make things happen when the button is clicked or even manipulate the style and text on the button itself.

What other elements do I want to store in a variable?

  • The input box — I’d like to retrieve whatever the user rights in the input box.
  • The answer paragraph — I’d like to change the Magic 8 Ball’s answer (“Likely”, “Reply Hazy”, etc.)
  • The paragraph containing the 8 — I’d like to get rid of that when I want to show the Magic 8 Ball’s answer!

Find these elements in the HTML and identify their id. Then, modeling your next lines of code after the line above where we stored the button in a variable, store these elements in JavaScript variables as well.

When you’ve declared those variables, check your answers against mine:

Make sure you have four variables declared in your script.js file. For ease of following along, I recommend naming your variables the same as mine.

Now that we have our variables, we can start manipulating our HTML!

Adding an event listener

When the user clicks the “Shake” button, we want the 8 to disappear from the Magic 8 Ball and an answer to be revealed.

The ultimate goal!

To accomplish this, we need to add an event listener to our button.

We can declare an event listener that waits for the button to be clicked like this:

The event listener is constantly checking if the button has been clicked. When it is clicked, the alert we added between the curly braces will pop up.

Put the code for an event listener BELOW your declaration of the variables. Test it out on the app preview. Does an alert come up when you click the button?

Yay! It works!

Adding Magic 8 Ball functionality

Okay, now you can delete the alert. What do we actually want to happen when the button is clicked? Well, I want to make sure that the user actually typed in a question.

Since I stored the HTML input box element in a variable called input, I can retrieve whatever the user typed with input.value. I can also find the length of their input with input.value.length (this isn’t so hard!).

When the button is clicked, I will check if the input value is less than one. If so, I send an alert telling the user to type in a question!

Test it out!

But I’ve also got to do something if the user does type in a question. I’m going to add an else branch to the if statement.

If the user does enter a question, first I want to make the 8 vanish from the screen. I can do this by setting the innerText of the variable eight to empty text: "".

Then I want to provide an answer. For now, I’ll do a placeholder and set the innerText of the variable answer to a dummy string like "answer".

Now my event listener looks like this:

Test it out! Type in a question and hit the “Shake” button. See if the dummy text “answer” appears!

If it doesn’t, check for typos or open the JavaScript console if you have experience with that kind of thing.

Generating random answers with arrays

I’m going to tell you a secret: there’s no such thing as randomness. Those “randomly generated” numbers are actually generated by formulas that attempt to achieve randomness, but are really just formulas at the end of the day.

We’re going to do the same thing! We’re going to detect the length of the user’s input and use that to generate a “random” answer from the Magic 8 Ball.

But first, we need an array of options. I mean “array” literally — that is the term for a list-like data structure that can hold a variety of other items, like strings (“yes”, “no”) or numbers. We’re going to make an array of strings (words/phrases in quotes) to store the Magic 8 Ball’s potential answers.

Add this code along with the rest of your variables, above the event listener:

Right now, it’s a pretty simplistic Magic 8 Ball. We’ll flesh that out later.

Computers count starting at 0, so in order to access a “random” element from the array, we’re going to pick a number from 0–2 and retrieve the correspondingly numbered item from the array.

To do this, I’m going to calculate the length of the user’s input text and perform a modulus operation on it. Modulus operators return the remainder after division — for instance, 5 divided by 2 has a remainder of 1, so 5 mod 2 equals 1.

I want to calculate input.value.length mod options.length (the number of answers we have to choose from). This will result in a remainder that ranges from 0 to the last element of the options array. For our current array, it will result in a number from 0–2.

Make sure you declared your options array ABOVE your event listener. Move it now if you haven’t.

Now you can modify your event listener to calculate a “random” number and retrieve the appropriate answer from the options list:

Can you find the modulus operator? It looks like a percent sign: %. What variable is storing the “random” number generated by the modulus operation? (If you said num, you’re right!)

Also notice how we retrieved the element from the options array using brackets to specifically retrieve the element at the location of num (at this point, a location between 0–2).

Test out your Magic 8 Ball now. Is it saying “yes”, “no”, or “maybe”? Does it vary its answer when you type in different answers?

If it doesn’t, compare your code against the solution code or, if you’re feeling brave, pop open the JavaScript console.

If it’s working, congratulations on building a fully functional web app!

Writing the Magic 8 Ball answers

Now’s the fun part — supply all the different answers for the Magic 8 Ball! You can write your own totally crazy answers, wacky fortunes, or just take all the default Magic 8 Ball answers like I did:

Make sure all your answers are surrounded by quotation marks, and that you separate your answers with commas that are outside of the quotation marks. Computers get very confused when all the syntax isn’t exactly as they want it.

Happy coding!

Make the Magic 8 Ball your own

Kelly Lougheed

Written by

Software developer & educator