JavaScript and HTML

Begin Programming with JavaScript JavaScript and HTML

The typical use case of JavaScript in the browser is to interact with HTML elements. HTML elements are the fundamental building blocks of website graphical user interface.

We’ve been using prompt and alert for input and output purposes, and that’s a classical programming style. But in practice, web page user interface is created using HTML elements in an event-driven programming style.

In this chapter, we’re going to replace alert and prompt with some common HTML elements.

Although we won’t cover everything about HTML, we’ll go over the big picture of using JavaScript with HTML.

The Goal

Reusing the code from Chapter 4, we’re going to make an HTML version of the same program.

↓ The user would be able to type a list of numbers in a textbox. When they click the button, the program will show the output right below it.

image

The user experience is very similar to the original program. But instead of using the popup, we’re displaying the elements on the page.

The Code

Make a new copy of the chapter-4 folder, and rename it to chapter-8:

chapter-4
chapter-8

We’re going to comment out the JavaScript code for now, but we will need them later.

/*
let userInput = prompt("Please enter the numbers:");
let inputItems = userInput.split(" ");

let sum = 0;

for(let i = 0; i < inputItems.length; i++){
  if(!isNaN(inputItems[i])){
    sum = sum + parseInt(inputItems[i]);
  }
}

alert("The sum is " + sum);
*/

unpack:

Use /* and */ to comment out multiple lines of code at the same time. This style of commenting doesn’t require putting // on every single line.

Set up the HTML

In the index.html file, we can create an element with an opening tag and closing tag.

<p>Hello World</p>

unpack:

p stands for paragraph. This is a paragraph element, and it’s used for displaying text content.

The closing tag has a slash.

↓ We have to put the paragraph element inside the <body> element.

<!DOCTYPE html>
<html>
<body>
<p>Hello World</p>
<script src="main.js"></script>
</body>
</html>

unpack:

The <p> element should come before the <script> element because the JavaScript code depends on the HTML code, the depended code has to exist before the depending code.

Save and open the file in the browser, you’ll see Hello World but this time not in a popup box.

↓ To make your life easier, you should use the tab key to indent each inner level.

right

This will make your code much easier to read, hence, much easier to detect potential problems.

import the Element

Remove the Hello world text from the paragraph element, we need it to be empty so we can use it as an output element. We’re going to set its content dynamically inside JavaScript.

<p></p>

Before we can use this element in JavaScript, we have to give it a unique id. It’s like giving a name to an element.

<p id="output"></p>

unpack:

You can name the id whatever you want, but just like a variable, the id should be sensible. output is the id we give to this element.

↓ Back in the JavaScript file, we can import the output element into JavaScript.

let output = document.getElementById("output");

document.getElementById does exactly what it says, getting an element by using an ID. We’re importing the element with the output ID into the JavaScript world.

Now that we have the output element in JavaScript, we can change its content to whatever we want:

let output = document.getElementById("output");
output.innerHTML = "Hello from JavaScript";

unpack:

The value we’re getting from getElementById is an object, and we’re changing its innerHTML property.

If you check in the browser, you should see Hello from JavaScript.

What happened was, the browser runs the HTML code first, since it appears before the JavaScript code. So the element starts out blank, then the browser runs the JavaScript code, and that updates the element to Hello from JavaScript.

The Input Elements

A paragraph element is an output element for displaying information to the user. On the other hand, button and textbox are input elements that we can use to get data from the user, and they’re often used together to create a unified inputting experience.

image

Textbox:

<input type="text" id="textbox">

Button:

<input type="button" id="submitButton" value="submit">

unpack:

The value attribute is for showing the text on the button.

An input element has no closing tag because an input element can’t contain another element.

Both the textbox and the button are created using the same input element but with a different type attribute. That means by changing the type attribute we can get a different input element. Here are some other types of input elements:

checkbox

image

radio

image

password

image

This is just to showcase the flexibility of the input element. We won’t be using all of these input types in this program.


↓ Next, put the textbox and button elements right before the output element.

...
<input type="text" id="textbox">
<input type="button" id="submitButton" value="submit">
<p id="output"></p>
...

That’s all the code we need in the HTML side.

↓ In the JavaScript side, we have to import the new elements into JavaScript:

// NEW
let textbox = document.getElementById("textbox");
let submitButton = document.getElementById("submitButton");

let output = document.getElementById("output");

Listen to event

Instead of using a function like prompt to get the user input, we have to set an event handler function for the button.

An event handler is a function that gets connected to an element. When something happens to an element, this function will get called automatically.

image

Another name for event handler is event listener because we’re listening to an event and react to it. These two names are interchangeable in JavaScript.

↓ We’re going to use the addEventListener method to connect an event handler function to the button element.

let output = document.getElementById("output");
let textbox = document.getElementById("textbox");
let submitButton = document.getElementById("submitButton");

submitButton.addEventListener("click", function(){

});

unpack:

The first parameter for the addEventListener function is an event name. We’re listening to the click event of the button here. We’ll go over the concept of event in a moment.

The second parameter should be an event handler function. This is the first time we’re passing a function to another function as an argument.

The event handler is just a regular function but without a name. The function is empty at the moment.

Update the element

Next, we’re going to move all the code from the Chapter 4 program into the event handler, but we need to modify it in a few places:

...
submitButton.addEventListener("click", function(){
  let userInput = textbox.value; // CHANGE
  let inputItems = userInput.split(" ");

  let sum = 0;

  for(let i = 0; i < inputItems.length; i++){
    if(!isNaN(inputItems[i])){
      sum = sum + parseInt(inputItems[i]);
    }
  }

   // CHANGE ↓
  output.innerHTML = "The sum is " + sum;
});

↓ Instead of using prompt to get the user input, we’re using the value property of the textbox element. And instead of using alert to display the output, we’re using the innerHTML property to update the output element.

screen

Event

Now let’s talk about what exactly an event is.

↓ When the user clicks the button, an event will be triggered, and in turn, the browser will run the corresponding event handler.

image

An event is like a notification or a signal that you can listen and react to.

When we connect an event handler to an element, we have to connect it to an element via a specific event because a single element can trigger multiple different events.

image

We’re using the click event here, but there are many other events besides click.

right

Here’s a list of common events and the corresponding user actions that will trigger them:

  • click - when clicking the element
  • dblclick - when double-clicking the element
  • mouseenter - when the mouse moves into the element
  • mouseleave - when the mouse moves out of the element
  • mousemove - whenever the mouse moves inside the element
  • contextmenu - when right-clicking the element

callback

A function that gets passed as an argument to another function is a callback function (or just callback for short). The main characteristic of a callback is that we don’t have to call it directly, it gets called automatically when the time is right. That’s why we don’t need a name for a callback function.

right

↓ Optionally, we can define the callback just like a normal function with a name, and pass the name as the argument.

right

But this is only useful if two different events are sharing the same handler, so usually, we just pass the function directly without creating a variable.

foreach

Callback functions are used everywhere in JavaScript programming, they are not limited to just being event handlers. For instance, the array method forEach can help us to loop through an array without using a for loop, and it takes a callback function as a parameter.

Here’s a comparison between using a for loop and using the forEach method with a callback function to do the same thing:

let items = [1, 2, 3];

// Using for loop
for(let i = 0; i < items.length; i++){
  let item = items[i];
  console.log(item);
}

// Using forEach
items.forEach(function(item){
  console.log(item);
});

This callback function will get called three times because there are three items in the items array.

right

Each time, a different item from the array will get passed to the function as the argument.

Recap

index.html

<!DOCTYPE html>
<html>
  <body>
    <input type="text" id="textbox">
    <input type="button" id="submitButton" value="submit">
    <p id="output"></p>
    <script src="main.js"></script>
  </body>
</html>

main.js

let output = document.getElementById("output");
let textbox = document.getElementById("textbox");
let submitButton = document.getElementById("submitButton");

submitButton.addEventListener("click", function(){
  let userInput = textbox.value;
  let inputItems = userInput.split(" ");

  let sum = 0;

  for(let i = 0; i < inputItems.length; i++){
    if(!isNaN(inputItems[i])){
      sum = sum + parseInt(inputItems[i]);
    }
  }
  output.innerHTML = "The sum is " + sum;
});

unpack:

All the code

The general JavaScript-HTML workflow is:

  1. Set up the elements in HTML
  2. Import the elements into JavaScript using document.getElementById
  3. Listen to an event on the input element using addEventListener with an event handler.
  4. In the event handler, update the output element.

Exercise

Add another button called reset to the existing program. Set a new event handler for the reset button. When the reset button is clicked, the textbox will become empty.

Solution

index.html

<input type="button" id="resetButton" value="reset">

unpack:

Put this element right before the submitButton element.

The new element is almost the same as the submitButton element but with a different id and value.

 

main.js

...
let resetButton = document.getElementById("resetButton");

resetButton.addEventListener("click", function(){
  textbox.value = "";
});

unpack:

The handler function is just one line of code that sets the textbox content with an empty string.