facebook google plus twitter
Webucator's Free JavaScript Tutorial

Lesson: Event Handlers

Welcome to our free JavaScript tutorial. This tutorial is based on Webucator's Introduction to JavaScript Training course.

In this lesson, you will learn how to work with event handlers.

Lesson Goals

  • Learn to understand what JavaScript event handlers are.
  • Learn to recognize commonly-used event handlers.
  • Learn to use dot notation and square-bracket notation.
  • Learn to get DOM elements with getElementById().
  • Learn to get DOM elements with querySelector().
  • Learn to access element and text nodes hierarchically.

Event Handlers

Event handlers are attributes that force an element to "listen" for a specific event to occur. Event handlers all begin with the letters "on".

We might, for instance, listen for a user to click on a specific div element, listen for a form submission, or listen for the user to pass his or her mouse over any input element of a given class.

The table below lists commonly-used HTML event handlers with descriptions.

HTML Event Handlers
Event Handler Elements Supported Description
onblur a, area, button, input, label, select, textarea the element lost the focus
onchange input, select, textarea the element value was changed
onclick All elements except applet, base, basefont, bdo, br,
font, frame, frameset, head, html, iframe,
isindex, meta, param, script, style, title
a pointer button was clicked
ondblclick All elements except applet, base, basefont, bdo, br,
font, frame, frameset, head, html, iframe,
isindex, meta, param, script, style, title
a pointer button was double clicked
onfocus a, area, button, input, label, select, textarea the element received the focus
onkeydown All elements except applet, base, basefont, bdo, br,
font, frame, frameset, head, html, iframe,
isindex, meta, param, script, style, title
a key was pressed down
onkeypress All elements except applet, base, basefont, bdo, br,
font, frame, frameset, head, html, iframe,
isindex, meta, param, script, style, title
a key was pressed and released
onkeyup All elements except applet, base, basefont, bdo, br,
font, frame, frameset, head, html, iframe,
isindex, meta, param, script, style, title
a key was released
onload body, frameset the document or all the frames have been loaded
onmousedown All elements except applet, base, basefont, bdo, br,
font, frame, frameset, head, html, iframe,
isindex, meta, param, script, style, title
a pointer button was pressed down
onmousemove All elements except applet, base, basefont, bdo, br,
font, frame, frameset, head, html, iframe,
isindex, meta, param, script, style, title
a pointer was moved within
onmouseout All elements except applet, base, basefont, bdo, br,
font, frame, frameset, head, html, iframe,
isindex, meta, param, script, style, title
a pointer was moved away
onmouseover All elements except applet, base, basefont, bdo, br,
font, frame, frameset, head, html, iframe,
isindex, meta, param, script, style, title
a pointer was moved onto
onmouseup All elements except applet, base, basefont, bdo, br,
font, frame, frameset, head, html, iframe,
isindex, meta, param, script, style, title
a pointer button was released
onreset form the form was reset
onselect input, textarea some text was selected
onsubmit form the form was submitted
onunload body, frameset the document or all the frames have been removed

The getElementById() Method

A very common way to reference HTML elements is by their ID using the getElementById() method of the document object as shown in the example below. Once we have the element - that is, once we get a given div, p, input or other DOM element via the getElementById() method - we can then listen for events on that element. Let's look at an example:

Code Sample:

EventHandlers/Demos/getElementByID.html
---- C O D E   O M I T T E D ----

<p>
	<span onclick="document.getElementById('divRed').style.backgroundColor = 'red';">
		Red</span> |
	<span onclick="document.getElementById('divOrange').style.backgroundColor = 'orange';">
		Orange</span> |
	<span onclick="document.getElementById('divGreen').style.backgroundColor = 'green';">
		Green</span> |
	<span onclick="document.getElementById('divBlue').style.backgroundColor = 'blue';">
		Blue</span>
</p>
	<div id="divRed">Red</div>
	<div id="divOrange">Orange</div>
	<div id="divGreen">Green</div>
	<div id="divBlue">Blue</div>
</body>
</html>

Code Explanation

Clicking the color names listed horizontally across the top of the page sets the style of the corresponding div element, whose id is gotten via a call to getElementById().

Using Event Handlers

Duration: 15 to 25 minutes.

In this exercise, you will use some of the event handlers from the table above to allow the user to change the background color of the page.

  1. Open EventHandlers/Exercises/color-changer.html for editing.
  2. Modify the page so that...
    • when the page loads, an alert pops up reading "The page is loading!".
    • when the "Red" button is clicked, the background color turns red and an alert pops up reading "The background color will be Red."
    • when the "Green" button is double-clicked, the background color turns green and an alert pops up reading "The background color will be Green."
    • when the "Orange" button is clicked down, the background color turns orange and an alert pops up reading "The background color will be Orange."
    • when the mouse button is released over the "Blue" button, the background color turns blue and an alert pops up reading "The background color will be Blue."

Code Sample:

EventHandlers/Exercises/color-changer.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>Color Changer</title>
<link href="style.css" rel="stylesheet">
<script>
	window.alert("The page is loading.");
</script>
</head>
<body>
<form>
	<p>Click the button to turn the page:
	<input type="button" value="Red"></p>
	<p>Double click the button to turn the page:
	<input type="button" value="Green"></p>
	<p>Click down on the button to turn the page:
	<input type="button" value="Orange"></p>
	<p>Release the mouse while on the button to turn the page:
	<input type="button" value="Blue"></p>
</form>
<hr>
</body>
</html>

Challenge

  1. Add functionality so that when the user presses any key, the background color turns white.
  2. Add a "Black" button. When the user hovers over this button and presses the mouse button down, the background color should turn black. When the user releases the mouse button, the background color should turn white.

Solution:

EventHandlers/Solutions/color-changer.html
---- C O D E   O M I T T E D ----

<script>
	window.alert("The page is loading.");
</script>
</head>
<body>
<form>
	<p>Click the button to turn the page:
	<input type="button" value="Red"
		 onclick="document.body.style.backgroundColor = 'red'; 
				alert('The background color is now Red.');"></p>
	<p>Double click the button to turn the page
	<input type="button" value="Green"
		 ondblclick="document.body.style.backgroundColor = 'green'; 
				alert('The background color is now Green.');"></p>
	<p>Click down on the button to turn the page
	<input type="button" value="Orange"
		 onmousedown="document.body.style.backgroundColor = 'orange'; 
				alert('The background color is now Orange.');"></p>
	<p>Release the mouse while on the button to turn the page
	<input type="button" value="Blue"
		 onmouseup="document.body.style.backgroundColor = 'blue'; 
				alert('The background color is now Blue.');"></p>
</form>
<hr>
</body>
</html>

Challenge Solution:

EventHandlers/Solutions/color-changer-challenge.html
---- C O D E   O M I T T E D ----

<body onkeypress="document.body.style.backgroundColor = 'white'; 
				alert('The background color is now White.');">
<form>

---- C O D E   O M I T T E D ----

	<p>Press any key to turn the page back to white.</p>
	<p>Click the button to turn the page
	<input type="button" value="Black"
		 onmousedown="document.body.style.backgroundColor = 'black';" 
		 onmouseup="document.body.style.backgroundColor = 'white';"></p>
</form>
<hr>
</body>
</html>

Dot Notation and Square Bracket Notation

In the first lesson of this course we took a look at two ways in which we can access elements in JavaScript: dot notation and square bracket notation. Let's review these concepts again, since we will use both tactics repeatedly throughout this course.

Dot notation lets us refer to hierarchical DOM elements starting with the top-most element (window, say) then a set of dot-separated names, referencing elements by their name or id. For instance, to get an input element with id fname inside a form with id form1, we might use the following:

window.document.form1.fname

If the form were the first form on the page, we could also refer to it this way:

window.document.forms[0].fname

Since a document can have multiple form elements as children, we can reference the specific form by its order on the page, as an element in the collection of forms. Arrays and collections in JavaScript start with index 0, so the first form on the page would be forms[0].

Similarly, we can reference objects with square bracket notation, where the argument of the brackets is the id of the element or the number-index of the element in a collection:

window['document']['form1']['fname']

// or

window['document']['forms'][0]['fname']

Both of the references above are equivalent to the dot-notation references we showed earlier and can be used interchangeably. With either dot notation or square bracket notation, keep in mind that the reference moves from general on the left to specific on the right. In our example, the window contains the document, which contains a form with id form1, which in turn contains an input element with id fname.

CSS Selectors

Here we present an introduction/review of CSS selectors. There are several different types of selectors:

  • Type
  • Descendant
  • Child
  • Class
  • ID
  • Attribute
  • Universal

Selectors identify the element(s) affected by the CSS rule.

Type Selectors

Type selectors specify elements by tag name and affect every instance of that element type. Looking again at a previous example:

               p {
	color: darkgreen;
	font-family: Verdana;
	font-size: 10pt;
}

This rule specifies that the text of every <p> element should be darkgreen and use a 10-point Verdana font.

Descendant Selectors

Descendant selectors specify elements by ancestry. Each "generation" is separated by a space. For example, the following rule states that <strong> tags within <p> tags should have red text:

               p strong {
	color: red;
}

With descendant selectors generations can be skipped. In other words, the code above does not require that the <strong> tag is a direct child of the <p> tag.

Child Selectors

Child selectors specify a direct parent-child relationship and are indicated by placing a > sign between the two tag names:

               p > strong {
	color: red;
}

In this case only <strong> tags that are direct children of <p> tags are affected.

Class Selectors

In HTML, almost all elements can take the class attribute, which assigns a class name to an element. The names given to classes are arbitrary, but should be descriptive of the purpose of the class. In CSS, class selectors begin with a dot. For example, the following rule creates a class called "warning," which makes the text of all elements of that class bold and red:

               .warning {
	font-weight: bold;
	color: #ff0000;
}

Following are a couple of examples of elements of the warning class:

<h1 class="warning">WARNING</h1>
<p class="warning">Don't go there!</p>

If the class selector is preceded by an element name, then that selector only applies to the specified type of element. To illustrate, the following two rules indicate that h1 elements of the class "warning" will be underlined, while p elements of the class "warning" should not be:

               h1.warning {
	color: #ff0000;
	text-decoration: underline;
}
p.warning {
	color: #ff0000;
	font-weight: bold;
}

Because both rules indicate that the color should be red (#ff0000), this could be rewritten as follows:

               .warning {
	color: #ff0000;
}
h1.warning {
	text-decoration: underline;
}
p.warning {
	font-weight: bold;
}

Note that you can assign an element any number of classes simply by separating the class names with spaces like this:

Syntax

<div class="class1 class2 class3">...

ID Selectors

As with the class attribute, in HTML, almost all elements can take the id attribute, which is used to uniquely identify an element on the page. In CSS, ID selectors begin with a pound sign (#) and have arbitrary names. The following rule will indent the element with the "maintext" id 20 pixels from the left and right:

               #mainText {
	margin-left: 20px;
	margin-right: 20px;
}

<div id="mainText">
	This is the main text of the page...
</div>

Attribute Selectors

Attribute selectors specify elements that contain a specific attribute. They can also specify the value of that attribute.

The following selector affects all links with a target attribute:

               a[target] {
	color: red;
}

The following selector would only affect links whose target attribute is "_blank".

               a[target="_blank"] {
	color: red;
}

The Universal Selector

The universal selector is an asterisk (*). It matches every element.

               * {
	color: red;
}

Grouping

Selectors can share the same declarations by separating them with commas. The following rule will underline all i elements, all elements of the class "warning" and the element with the id of "important."

i, .warning, #important {
	text-decoration: underline;
}

querySelector()

We can exploit the various CSS selectors, as described above, by using querySelector(). The document.querySelector() method returns the first element found that matches its argument. Unlike the getElementById() method, which finds an element by its id, document.querySelector() offers us a way to find an element by tag name, class name, or id. The following line of code would return the first list item found in an ol tag:

var firstOrderedListItem = document.querySelector("ol>li");

Let's look at an example:

Code Sample:

EventHandlers/Demos/query-selector.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>querySelector()</title>
<link href="style.css" rel="stylesheet">
<script>
	function setColors() {
		var firstParagraph = document.querySelector("p");
		firstParagraph.style.backgroundColor='red';
		var spanText = document.querySelector("span");
		spanText.style.backgroundColor='blue';
		var firstListItem = document.querySelector("li");
		firstListItem.style.backgroundColor='green';
		var listItemClassSpecial = document.querySelector("li.special");
		listItemClassSpecial.style.fontStyle='italic';
	}
</script>
</head>
<body onload="setColors();">
	<p>This is the first paragraph. This is the first paragraph. This is the first paragraph. This is the first paragraph. This is the first paragraph. This is the first paragraph.</p>
	<p>This is the second paragraph. This is the second paragraph. This is the second paragraph. This is the second paragraph. <span>This text is wrapped in a span tag.</span> This is the second paragraph. This is the second paragraph. This is the second paragraph.</p>
	<ul>
		<li>List item 1</li>
		<li>List item 2</li>
		<li class="special">List item 3</li>
		<li>List item 4</li>
	</ul>
</body>
</html>

Code Explanation

The markup for our page has two paragraphs, the second of which includes some text wrapped in a span tag, followed by an unordered list with four items; the third list item has class special.

We use the event handler onload() to run our custom function setColors(); the onload event handler fires only after the DOM has been loaded for the page, ensuring that all tags, ids, and classes have been loaded and are accessible to our JavaScript code.

We use document.querySelector() to:

  • Find the first paragraph, and color it red.
  • Find the first span, and color it blue.
  • Find the first list item, and color it green.
  • Find the first list item with class special, and style it with italic text.

Let's have you try out using querySelector() with an exercise:

querySelector()

We can exploit the various CSS selectors, as described above, by using querySelector(). The document.querySelector() method returns the first element found that matches its argument. Unlike the getElementById() method, which finds an element by its id, document.querySelector() offers us a way to find an element by tag name, class name, or id. The following line of code would return the first list item found in an ol tag:

var firstOrderedListItem = document.querySelector("ol>li");

Let's look at an example:

Code Sample:

EventHandlers/Demos/query-selector.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>querySelector()</title>
<link href="style.css" rel="stylesheet">
<script>
	function setColors() {
		var firstParagraph = document.querySelector("p");
		firstParagraph.style.backgroundColor='red';
		var spanText = document.querySelector("span");
		spanText.style.backgroundColor='blue';
		var firstListItem = document.querySelector("li");
		firstListItem.style.backgroundColor='green';
		var listItemClassSpecial = document.querySelector("li.special");
		listItemClassSpecial.style.fontStyle='italic';
	}
</script>
</head>
<body onload="setColors();">
	<p>This is the first paragraph. This is the first paragraph. This is the first paragraph. This is the first paragraph. This is the first paragraph. This is the first paragraph.</p>
	<p>This is the second paragraph. This is the second paragraph. This is the second paragraph. This is the second paragraph. This text is wrapped in a span tag. This is the second paragraph. This is the second paragraph. This is the second paragraph.</p>
	<ul>
		<li>List item 1</li>
		<li>List item 2</li>
		<li class="special">List item 3</li>
		<li>List item 4</li>
	</ul>
</body>
</html>

The markup for our page has two paragraphs, the second of which includes some text wrapped in a span tag, followed by an unordered list with four items; the third list item has class special.

We use the event handler onload() to run our custom function setColors(); the onload event handler fires only after the DOM has been loaded for the page, ensuring that all tags, ids, and classes have been loaded and are accessible to our JavaScript code.

We use document.querySelector() to:

  • Find the first paragraph, and color it red.
  • Find the first span, and color it blue.
  • Find the first list item, and color it green.
  • Find the first list item with class special, and style it with italic text.

Let's have you try out using querySelector() with an exercise:

Working with querySelector()

Duration: 10 to 15 minutes.

In this exercise, you will practice working with JavaScript's querySelector() function.

  1. Open EventHandlers/Exercises/query-selector.html for editing.
  2. Add a click handler to the button so that the function setColor() is called when the user clicks the button.
  3. Write the contents of function setColor() to do the following:
    • Use prompt() to get from the user the element he/she wishes to color - expected input would be a tag (like p), a class (like .a), or an id (like #x).
    • Use prompt() to get from the user their desired color (like blue or red).
    • Use querySelector() to get the user's desired element, then set the color of that element.

Solution:

EventHandlers/Solutions/query-selector.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>querySelector()</title>
<link href="style.css" rel="stylesheet">
<script>
	function setColor() {
		var userElement = prompt("Element to color?", "");
		var userColor = prompt("What color?", "");
		document.querySelector(userElement).style.backgroundColor = userColor;
	}
</script>
</head>
<body>
	<button onclick="setColor();" type="button">Go</button>
	<ul>
		<li>Item 1</li>
		<li class="a">Item 2 | class "a"</li>
		<li>Item 3</li>
		<li class="b">Item 4 | class "b"</li>
		<li>Item 5</li>
		<li class="c">Item 6 | class "c"</li>
		<li>Item 7</li>
		<li id="x">Item 8 | id "x"</li>
		<li class="a">Item 9 | class "a"</li>
		<li>Item 10</li>
	</ul>
</body>
</html>

Code Explanation

We add onclick="setColor();" as an attribute to the button at the top of the page so that function setColor() is called when the user clicks the button.

We use prompt() to get from the user the desired element (storing it in variable userElement) and the desired color (storing it in userColor).

Lastly, we use the code

document.querySelector(userElement).style.backgroundColor = userColor;

to set the color of the first matched element supplied by the user:

  • If the user entered "ul" and "green", the entire unordered list would be colored green.
  • If the user entered "li" and "red", the first bullet would be colored red.
  • If the user entered ".b" and "blue", the fourth bullet would be colored blue.
  • If the user entered "#x" and "orange", the eigth bullet would be colored orange.
  • If the user entered ".w" and "red", nothing would happen, as there is no element with class "w". (Actually an error would occur, as the returned value of document.querySelector() would be null.)

Accessing Element and Text Nodes Hierarchically

JavaScript provides a variety of methods and properties that provide access to nodes - elements on the page - based on their hierarchical relationship. The most common and best supported of these are shown in the table below:

Properties for Accessing Element Nodes
Property Description
childNodes[] A nodeList containing all of a node's child nodes.
firstChild A reference to a node's first child node.
lastChild A reference to a node's last child node.
nextSibling A reference to the next node at the same level in the document tree.
parentNode A reference to a node's parent node.
previousSibling A reference to the previous node at the same level in the document tree.

As suggested by the square brackets, childNodes[] returns a collection of elements. The other properties return a single node.

These properties offer us a more flexible way to get elements on the page, relative to their parents, siblings, or children. We can do anything with the returned elements that we did previously with getElementById() or querySelector() - set the background color, change the font style, etc.

In the example below, we'll use the innerHTML property to get the HTML text contained inside the nodes we get. Let's take a look at how we might use these properties:

Code Sample:

EventHandlers/Demos/elementNodes.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>Accessing Element Nodes</title>
<link href="style.css" rel="stylesheet">
<script>
	function modify() {
		var childFirst = document.getElementById("list1").firstChild;
		childFirst.style.backgroundColor = "red";
		var childLast = document.getElementById("list1").lastChild;
		childLast.style.backgroundColor = "blue";
		var siblingPrev = childLast.previousSibling;
		siblingPrev.style.backgroundColor = "green";
		document.getElementById("message").innerHTML = 'First child text is <strong>'+childFirst.innerHTML+'</strong><br><br>Last child text is <strong>'+childLast.innerHTML+'</strong><br><br>Next to last (previous sibling) text is <strong>'+siblingPrev.innerHTML+'</strong>';
	}
</script>
</head>
<body>
	<button type="button" onclick="modify()">Go</button>
	<ul id="list1"><li>Item 1</li><li>Item 2</li><li>Item 3</li><li>Item 4</li><li>Item 5</li></ul>
	<p id="message"></p>
</body>
</html>

Code Explanation

Our simple page displays a button and five unordered list items, with text "Item 1", "Item 2", etc.

When the user clicks the button, the onclick event handler calls function Modify(), which does the following:

  • Gets the first child of the list using firstChild, and sets its background to red.
  • Gets the last child of the list using lastChild, and sets its background to blue.
  • Gets the next-to-last child of the list using previousSibling (relative to the already-gotten childLast), and sets its background to green.
  • Sets the innerHTML of the paragraph (at the bottom of the page) to display the text from the first, last, and next-to-last list items we got earlier. Note that we use the JavaScript string concatentation operator, +, to build a string from our variables.

Note the special way in which we created the unordered list, with no spaces between any of the tags - that is, with all of the ul and li opening and closing tags on the same line. We did this because, if there were spaces between the tags, the spaces would have counted as "children" (as text nodes) and calls to properties like firstChild would have returned the text node (the space) rather than the first list item as we wished.

We'll ask you to try out these properties in the next exercise.

Working with Hierarchical Node Properties

Duration: 10 to 15 minutes.

In this exercise, you will practice working with JavaScript's hierarchical node properties.

  1. Open EventHandlers/Exercises/elementNodes.html for editing.
  2. Note that a click handler has been added to the button so that the function setFontSize() is called when the user clicks the button.
  3. Write the body of function setFontSize() to set the size of the font for each list item to be successively greater, with the first list item having font size 10px, the second 12px, etc.

Solution:

EventHandlers/Solutions/elementNodes.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>Element Nodes</title>
<link href="style.css" rel="stylesheet">
<script>
	function setFontSize() {
		var list = document.querySelector("ul");
		var childFirst = list.firstChild;
		childFirst.style.fontSize = "10px";
		var nextSib = childFirst.nextSibling;
		nextSib.style.fontSize = "12px";
		nextSib = nextSib.nextSibling;
		nextSib.style.fontSize = "14px";
		nextSib = nextSib.nextSibling;
		nextSib.style.fontSize = "16px";
		nextSib = nextSib.nextSibling;
		nextSib.style.fontSize = "18px";
		nextSib = nextSib.nextSibling;
		nextSib.style.fontSize = "20px";
		nextSib = nextSib.nextSibling;
		nextSib.style.fontSize = "22px";
		nextSib = nextSib.nextSibling;
		nextSib.style.fontSize = "24px";
		nextSib = nextSib.nextSibling;
		nextSib.style.fontSize = "26px";
		nextSib = nextSib.nextSibling;
		nextSib.style.fontSize = "28px";
	}
</script>
</head>
<body>
	<button onclick="setFontSize()" type="button">Go</button>
	<ul><li>Item 1</li><li>Item 2</li><li>Item 3</li><li>Item 4</li><li>Item 5</li><li>Item 6</li><li>Item 7</li><li>Item 8</li><li>Item 9</li><li>Item 10</li></ul>
</body>
</html>

Code Explanation

In function setFontSize() we use document.querySelector("ul") to get the unordered list, firstChild to get the first list item, and nextSibling to get each next item. Of course, if we were to use a loop (at which we'll look later in the course) we could have written much more economical code.