0% found this document useful (0 votes)
119 views393 pages

HTML 5000000

The document provides an overview of HTML elements, including the importance of URLs, the img element for images, and the role of alt text for accessibility. It explains the distinction between block and inline elements, along with their attributes, and emphasizes the necessity of the <head> and <body> tags in HTML structure. Additionally, it discusses the use of developer tools in browsers for inspecting and validating HTML code.

Uploaded by

chala
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
119 views393 pages

HTML 5000000

The document provides an overview of HTML elements, including the importance of URLs, the img element for images, and the role of alt text for accessibility. It explains the distinction between block and inline elements, along with their attributes, and emphasizes the necessity of the <head> and <body> tags in HTML structure. Additionally, it discusses the use of developer tools in browsers for inspecting and validating HTML code.

Uploaded by

chala
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 393

As Kelly noted at the end of the video: When you're linking to the top page (or

home page) of a site, the URL does not need a file path after the domain
name—so you will just see a single slash at the end of the address:

http://en.wikipedia.org/

And often this slash will be omitted altogether:

http://en.wikipedia.org

This would still be considered a fully-qualified URL.

In contrast, if we look at the URL for a file on your local system, we must give
the file path—in fact, most of the URL is the file path:

file:///Users/Kelly/notes.html

If we took away the file path from the above, we would just have:

file://

Images significantly enhance the web's appeal, featuring everything from cat pictures to
maps and advertisements. The img element in HTML, equipped with src (source URL)
and alt (text description) attributes enable the inclusion of these visuals in web pages.
The alt attribute is crucial for accessibility, describing when images fail to load due to
network issues, are missing, or when assisting visually impaired users with screen
readers.

The img element points the browser to an image's location without embedding the file
into the HTML document, functioning as an empty element with no closing tag. It
integrates directly into the text, influencing layout based on its size. This setup
underscores the importance of thoughtfully using images in web design to ensure
aesthetic appeal and accessibility.

What about accessibility?


Alt text is essential for web accessibility, enabling screen readers to describe images to
users who are blind or have visual impairments, and ensuring content is accessible
when images cannot load or for those using text-based browsers. It also supports users
with cognitive disabilities and improves SEO by giving search engines context for
images.

Write a piece of HTML that will display the


image https://fakeurl.example.net/fish.png with the alt text "Fish".

Now you've learned about many more HTML elements! This page is a
summary of all the elements you've seen so far. You can use this page as a
reference if you forget how to use one of these elements in your code.

You can also download a PDF version of this page here(opens in a new tab) .

Block elements
Block elements are used for large sections of text, such as paragraphs,
headlines, or lists; and also for some other features such as video players and
tables.

A block element creates a (usually invisible) box in the browser display. By


default, this box takes up the full width of the display. The beginning of a block
always starts on a new line in the display.

Most block elements have a particular way they are displayed by default:
paragraphs have margins around them; lists have bullet-points or numbered
items; headlines are printed in large text. There is also a generic block
element, div , which has no special defaults.

 p — Paragraph. Text in a paragraph is separated visually from other


paragraphs by a small margin.
 ul and ol — Unordered and ordered lists. By default, ul lists are displayed
with bullet points, and ol lists with numbered items.
 li — List items inside a ul or ol list. The li element has to be nested
inside a ul or ol list; it can't occur on its own.
 Section headers, from h1 (largest) to h6 (smallest). Used for headlines,
section titles, and the like.
 div — A logical division of a page or document. Other block elements such as
paragraphs, lists, and headers can be nested inside a div .

You will see the div element much more in the next lesson. Because they
don't have any default display settings, div s are heavily used with custom
styling with CSS.

Inline elements
Inline elements do not create a full-width box on the display. They modify the
display of text, or insert other things into the text — such as line breaks,
images, or hyperlinks.

 em and strong — Emphasis. By default, text inside an em is displayed


as italic, and text in strong is displayed as boldface.
 br — Line break. (empty) A line break does not create a new paragraph; it only
marks the end of a line.
 sub and sup — Subscript and superscript. Useful for math and chemistry: I
have x +2x molecules of H O.
3 2
2

 mark — Highlighting. Not very often used, but it's kind of cool.

Some of the inline elements you've seen require attributes, extra information
besides the name of the element itself. Attributes are written inside the
opening tag of the element.

 img — Images. Needs a src attribute with a URL, and an alt attribute with
descriptive text.
 a — Hyperlinks. Needs an href attribute with a URL.

Images
The syntax for the img tag is like this:
<img src="Image URL here" alt="A description of the
image">

The URL of an image may be an absolute URL, such


as http://placebear.com/800/600 , or it may be a relative URL such
as images/wolves.jpg .

The alt text is used if the image can't be loaded, or if the user can't see
images — such as if the user is using a screen reader(opens in a new tab) .

Links
Hyperlinks allow the user to navigate from one page to another. They are
created using the a element. The destination of the link is written in an
attribute called href ; the link text appears as the contents of the a element.
Here's an example:

<a href="https://en.wikipedia.org/wiki/Hypertext"
target="_blank">

Wikipedia's "Hypertext" article

</a>

This code produces a link like this: Wikipedia's "Hypertext" article(opens in


a new tab).

A link within a single web site


Notice that the list items in this design are also hyperlinks! And if you click on
one of them, it will open in a new browser tab. If you want to do this in your
own links, you can add the attribute target="_blank" to the a element. Like
this:
<a href="https://example.com/" target="_blank">Example</a>

We suggest doing that in this exercise, or else the link will open inside the
workspace itself when you click on it.
For the images, you can
use https://placebear.com/150/150 and https://placecats.com/150/150 .
will open in a new browser tab. If you want to do this in your own links, you can add the
attribute target="_blank" to the a element. Like this:

<a href="https://example.com/" target="_blank">Example</a>

We suggest doing that in this exercise, or else the link will open inside the workspace
itself when you click on it.

For the images, you can


use https://placebear.com/150/150 and https://placecats.com/150/150 .

Start Workspace

Workspaces will shut down after 30 minutes of inactivity. Any running processes will
be stopped.
Start Workspace

Workspaces may take up to 5 minutes to start.


View Active Workspaces

## ⚠️Spoiler alert!

Our solution is below. You'll learn more effectively if you give the exercise a strong
effort before comparing your code with ours!
----

Solution
Here's our code, if you want to compare:

<p>
My favorite things:
</p>
<ol>
<li><a href="https://en.wikipedia.org/wiki/Bear"
target="_blank">Bears</a>
<li><a href="https://en.wikipedia.org/wiki/Kitten"
target="_blank">Kittens</a>
</ol>
<img src="https://placebear.com/150/150" alt="A picture of a bear.">
<img src="https://placecats.com/150/150" alt="A picture of a kitten.">

Are head and body required?


In one sense, no, but in another sense, yes.

The grammar of HTML does not require that you literally write
a <head> or <body> tag in your HTML code. Many web developers do write
these. However, if you don't, the browser will attempt to place them into your
code itself.

It needs to put the head element around certain elements that belong there,
such as title ; and to put the body element around the elements that form
the document's body. This means that all the head elements must appear
first, and the body elements after.

You can't have a head element, such as title , in the middle of your
document:

<h1>Here is a 😨 problem:</h1>

<p>This is a paragraph, which has to be part of the body.

<title>This is the title, which has to be part of the


head.</title>

<p>The title is not allowed to be in the middle of the


body!

So even if you choose not to literally write the <head> and <body> tags in your
document, the head and body elements are still created by the browser; and
the rest of the document needs to be consistent with this. But you must make
sure that the title and other head parts appear before any paragraphs, lists,
images, or other body parts.
You might see older HTML documentation that says these tags are required. This was
true in XHTML, an older version of HTML. Today's browsers use HTML5, which does
not require them.
In the next lesson, you will learn much more about how the browser
understands and displays web pages, as you learn about Cascading Style
Sheets.
Task List
Now that you know about the <html>, <head>, and <body> elements, add them to
your notes file.

Everything in your page should fit into this overall structure:

<!DOCTYPE html>

<html lang="en">

<head>

<title>Title of your page</title>

</head>

<body>

Content goes here! (Things like paragraphs, links,


and images.)

</body>

</html>

You may also want to describe these elements a little. What are some examples of
things that you might put in the <head>? How about the <body>? And what would go
inside the <html> element?

When you're first learning HTML, some of the terms can easily get scrambled in your
head. In particular, it's not uncommon to start mixing up terms like heading, head, title,
and file name. So let's get some practice sorting out what is what.

For the next exercise, have a look at this notes page that is loaded up in a browser
window:
Try the validator!
Take a look at the following HTML. How many error messages do you think
the validator will give for it?

<!DOCTYPE html>

<html>

<head>

<title>This is great HTML!</title>

</head>

<body>

<img src="wonderful.png">

Such a wonderful page.</p>

</body>

</html>
Copy and paste it into the "Direct Input" tab of the validator
at https://validator.w3.org/(opens in a new tab) .

Validating HTML

How many errors do you get? Type the number of errors below.

Note: The validator may also give you warnings as well as errors. This question is just
asking about errors (don't count the warnings in your answer).

The validator is stricter


Web browsers are very lenient about how they interpret HTML. They work around small
errors and omissions. The quizzes you have seen in this lesson have been relatively
lenient as well. The HTML validator is intentionally stricter than actual browsers.

For instance, if you write an img element with no alt attribute, a typical browser will
display it just fine. But the language requires the alt attribute to provide a textual
description of an image; this helps search engines and also users with visual
disabilities. By reporting a missing alt attribute as an error, the validator makes sure
that valid HTML will be more accessible.

... but it can't catch everything


The validator cannot tell whether you gave your document a good title. It can't tell
whether the alt attribute contains an accurate description of the image. The validator
won't notice if you wrote <html lang="de"> (saying that your document is in
German) on a document that is actually written in Korean. It is still up to you to make
sure that your HTML says what you mean it to say.
But what does it mean?!
You will definitely sometimes run into validation errors that you don't understand. This is
a normal part of being a programmer, so it's important to develop skills for working
through them!

When you do see an error that you're not sure about, here are a few things you can try:

 Copy and paste the error into your favorite search engine.
 Search Knowledge(opens in a new tab) to see if someone has previously
encountered this error. If they haven't, you can post a question about it
yourself!
 Share the error with others (such as other students or a mentor).

You just finished your first full lesson on writing HTML! 📄🎉

Let's quickly summarize what we went over in this lesson:

 The Web. We talked about what the Web is and—at a basic level—how it
works.
 Tools for Editing. You practiced editing web pages using a text editor and
testing your work in a browser.
 HTML. You learned the fundamentals of HTML, the computer language we
use to structure and write webpages.
 URLs. You learned about URLs, the addresses that we use to refer to
documents and sites on the web.

When you click the Next button, you'll see a pop-up that will ask you to rate
the lesson. After you select a rating, you'll also see a box where you can write
any comments you want to share with us. We love to hear from you!

Update: A Note From Abe


Since we launched this course, many of you have sent us a whole bunch of
feedback! I have personally read every single one of your message and I've made
a whole bunch of improvements to the lessons based on your experiences
and ideas. 🛠

I can't tell you how much I enjoy reading your comments—so please, keep
'em coming!

Happy learning!

– Abe 😁
In this lesson you're going to learn how to add style to your web pages using
the Cascading Style Sheets (CSS) language. We'll learn about a whole
bunch of key concepts in this lesson, including:

 Tree structures. It's not immediately obvious, but the HTML code for your
web page has a branching hierarchy or tree structure. Understanding this
structure will help you apply style to your page more effectively and efficiently.
 Using CSS and HTML together. HTML and CSS are different languages, but
we'll learn how to use them together. We'll actually learn three different ways
to integrate CSS with the HTML of your web page.
 But also separating them. Although they work closely together, we'll also
learn how to separate our CSS, which defines the style of the page, from the
HTML, which defines the structure. This separation of concerns will make our
web development far more efficient.
 A whole lot of style properties. We'll learn how improve the look of our
HTML pages with CSS style properties—from changing the color of your text
to completely changing the layout.

This lesson is definitely more challenging than the last, but we hope you'll
stick with it because the payoff is well worth the work! You'll be tackling some
pretty sophisticated concepts that will dramatically improve your coding
abilities. Not only will you learn far more powerful ways to improve your web
pages, but at the same time you'll also be stretching your knowledge of
computer language syntax. You'll get a better understanding of how computer
languages are put together, and that will serve you well throughout your
journey as a developer.
How to Access Developer Tools in Your browser
The browser shown in the video is Google Chrome, which is what we recommend—but
most modern browsers have developer tools that work similarly. Here are instructions
for a few different browsers:

Google Chrome
 Open the Chrome menu at the top right of the browser window (the three
vertical dots) and select Tools > Developer Tools.
 You can also simply right-click on any page element and select Inspect.

Safari
1. From the menu bar, select Safari > Preferences, and click Advanced.
2. At the bottom of the box, check the "Show Develop menu in menu
bar" checkbox.
3. Choose Develop > Show Web Inspector.

Mozilla Firefox
 From the menu bar, select Tools > Web Developer > Inspector.
 You can also simply right-click on any page element and select Inspect.

Collapsing / Expanding Elements in Developer


Tools
Note that developer tools will often collapse elements, so you may need to expand them
to see what other elements are nested inside.

For example, in the animated gif below, we can see that Chrome developer tools has
collapsed the head element and it looks like this page doesn't have much HTML on it—
but if we expand the head by clicking on the little triangle dropdown, there are a bunch
of other elements nested inside:

Quiz 1: Hello world!


Use this tree diagram for the quiz below.

(As in Chrome Developer Tools, the "quote marks" just indicate a text element and
aren't literally in the page.)

Example HTML and CSS


Here's the HTML and CSS for the example shown in the middle of this video:

<!DOCTYPE html>
<html>
<head>
<title>Listy list</title>
<style>
p { color: red; }
ol { display: flex; }
li { margin: 20px; }
</style>
</head>
<body>
<p>These are some red red words.</p>
<ol>
<li>Apple apple berry berry sauce sauce sauce.<br>
Cook it on the stove and serve it to your boss.
<li>Betty bought a bit of butter,
but the butter's burning bitter.<br>
<li>Crisp cookies claim Charlie's cookout
crown.<br> Clever Clara
clocked the crows at <em>c</em> (clearly
connivance!)
<li>Daring drivers drove down Devil's Ditch in
Dodges.
<li>Evil eggs explode everywhere. Eww!
</ol>
</body>
</html>
By the way, when styles are applied directly to an HTML element using
the style attribute, these are called inline styles.

The idea is that the style is being applied directly in the same line as the HTML element
that it is styling. (In contrast, when we use the style element, the style is separated—
it's not in the same line.)
The HTML in the workspace below has three paragraphs of text. Add a style attribute
(an inline style) to each element to make it a different color.
# ⚠️Spoiler alert!

Our solution is below. You'll learn more effectively if you give the exercise a strong
effort before comparing your code with ours!
----

Solution
Here's our code:

<p style="color: red">Make me red!</p>


<p style="color: green">Make me green!</p>
<p style="color: blue">Make me blue!</p>
## ⚠️Spoiler alert!

Our solution is below. You'll learn more effectively if you give the exercise a strong
effort before comparing your code with ours!
----

Solution
<p style="text-align: center">This is a haiku</p>
<p style="text-align: center">So I want each line centered</p>
<p style="text-align: center">Let’s make it stylish</p>

Question 2 of 2
Here is a variation on the above code:

<p style="text-align: center;">This is a haiku</p>

<p style="text-align: center;"> So I want each line centered</p>

<p style="text-align: center;">Let’s make it stylish</p>

On the last page, we looked at how to style some text in blue:

color: blue

And how to center the text:

text-align: center

But what if you wanted to do both of these things at the same time? This turns out to be
pretty easy. All you have to do is put one after the next—and use a semicolon ; to
indicate where one ends and the next begins:

<p style="color: blue; text-align: center;">Hello world!


</p>

In the workspace below, give this a try! We encourage you to try to type this from
memory (referring back to the above example when you need to), rather than copying
and pasting it into the workspace. The act of trying to type it in for yourself will help you
build a stronger memory.
Note that when we only have one property, the semicolon is optional—we can
either include it or not and it won't make a difference. In other words, we can
do this:

<p style="color: blue;">Hello world!</p>

Or this:

<p style="color: blue">Hello world!</p>

And it will work the same. It's only when we have more than one that
we must include a semicolon to separate each of them:

<p style="color: blue; text-align: center">Hello world!


</p>

If we left out the semicolon at the end of blue; , this line would not work
correctly:

<p style="color: blue text-align: center">Hello world!


</p>

If you try this in the workspace, you'll see that neither of these styles get
applied (the text will be neither blue nor centered). So if you find that your
styles are not showing up, check for small syntax errors—like a missing
semicolon!
OK, so you've tried out inline styles that use the style attribute; now let's look at how
to apply styles using the style element.

Quiz Question
Just to make sure it's fresh in your mind, which of these examples use
inline style attributes and which use a separate style element?
Separate style element
Inline style attribute

Code
How is the style applied?
<p style="text-align: center;">I'm centered!</p>
<style>
p { text-align:center; }
</style>
<p>I'm centered!</p>
Submit

In the workspace below, you'll find some p elements that have been centered using
inline styles.

Remove the three inline styles and, instead, use a single, separate style element to
center all of the p elements.

Start Workspace

Workspaces will shut down after 30 minutes of inactivity. Any running processes will
be stopped.
Start Workspace

Workspaces may take up to 5 minutes to start.


View Active Workspaces

## ⚠️Spoiler alert!

Our solution is below. You'll learn more effectively if you give the exercise a strong
effort before comparing your code with ours!
----

Solution
<style>
p { text-align: center; }
</style>

<p>This is a haiku</p>
<p>So I want each line centered</p>
<p>Let’s make it stylish</p>

CSS Rulesets
A CSS ruleset is made up of a selector and a declaration block.

Selectors
Selectors indicate which HTML elements the ruleset will apply to. For example, consider
this ruleset:

li {

color: green;

In this example, li is the selector—meaning that whatever we put between the curly
braces { } will be applied to all list item li elements on the page.

Declaration Blocks
A declaration block describes how the ruleset will modify the elements. In the above
example, the declaration block is saying that all li elements will be modified by
changing their font colors to green.
A declaration block can have multiple declarations inside of it. For example, consider
this ruleset:

p {

background-color: blue;

font-size: 20px;

The declaration block is everything other than the selecter p :

{
background-color: blue;
font-size: 20px;
}
And this declaration block contains two individual declarations. One is:

background-color: blue;

And the other is

font-size: 20px;

Properties and Values


You can break the syntax of a declaration down even further. A declaration is made up
of a property and a value. For example, in this declaration…

background-color: blue;

…the property would be background-color and the value would be blue .

CSS Selectors
CSS selector. Tell the browser which elements the rule will affect.

CSS Selectors: Type


One example of a type of CSS selector is called type. If you want to use type
selector to style all h1 elements, this is how you would write your CSS:

h1 {
font-family: serif;
}

CSS Selectors: Class and ID


The distinction between a class and an ID can be a bit confusing, so let's review them
both.
Class
A class is a group of things with the same characteristics. To create a class, you need
to use the attribute "class" in the HTML opening tag. Then in your CSS, you use the
same name you gave the class attribute in your HTML, except you place a . in front of
it.

Example:

//HTML

<div class="container">

<p> I'm inside a container! </p>

</div>

//CSS

.container {

border: 1px solid black;

In this example, the class name is container . Any element with the class
attribute container will receive the styling of border: 1px solid black; . So for
example, if you added class="container" to the paragraph element, that would also
get this same styling.

ID
An ID is when you'd apply characteristics to one element. To create an ID, you need to
use the attribute id in the HTML opening tag. Then in your CSS, you use the same
name you gave the id attribute in your HTML, except you place a # in front of it.

Example:

//HTML
<h1 id="main-heading"> Welcome to My Page! </h1>

//CSS
#main-heading {
background-color: orange;
}
If you want to apply a style to more than one element, you should always use a class.
You should only use an ID to style one element. IDs are unique.
If you like, you can download this review as a PDF by clicking here(opens in a new
tab).

Here are some important CSS terms that you've learned so far:

 DOM (or Document Object Model) is a tree structure with a node for each
HTML element, piece of text, image, and any other object in the web page.
 Selectors are one part of the CSS ruleset. They indicate which HTML
element(s) the rule is for.

Example:

h3 {

text-decoration: underline;

h3 is the selector in this example.

 Declaration blocks are the other part of the CSS ruleset, they say how the
rule will modify the elements indicated by selectors.

In the above example, the declaration block includes the declaration of text-
decoration: underline;.

 CSS rulesets are composed of a selector followed by a declaration block.

Here are some examples of CSS rulesets:

.navigation-links {
font-weight: bold;

color: aqua;

#footer {

width: 100%;

background-color: purple;

li {

font-size: 10px;

margin-bottom: 10px;

 type is the simplest kind of selector. It indicates the name of one type of
HTML element (such as em or li).

In the above example, the type selector would be li.

 class in HTML is an attribute that groups elements together that you want to
have the same style.

In the above example, the class selector would be .navigation-links.

 id is an attribute that must be unique to a single element, used to identify it.

In the above example, the ID selector would be #footer.


If you like, you can download this review as a PDF by clicking here(opens in a new
tab).
You've now learned about three kinds of CSS selectors: type, class, and ID!
Type selectors are used to apply a style to a particular type of HTML element,
like h1 or body . Type selectors are written using just the type name.

Class selectors are used to set the style for multiple HTML elements that have a
particular value for the class attribute. You can name a class anything you want! Class
selectors are written with a dot before the class: for elements such as <p
class="blue"> , the class selector is .blue .

ID selectors are used when the style is being applied to one HTML element, which has
to have an id attribute. There can be only one element with a particular id on a page.
You can also choose any name you want for an id , just like a class . ID selectors are
written using a # sign: for an element such as <div id="sidebar"> , the id selector
is #sidebar .
Use this HTML document to answer the quiz below.

<html>
<head>
<style>
.special {
color: purple;
}
p {
font-style: italic;
}
#important-information {
font-weight: bold;
}
</style>
</head>
<body>

<h1 class = "special">This header is special</h1>


<p>A nice paragraph in italics.</p>
<h1>This header isn't so special.</h1>
<p>And this paragraph will be in italics too!</p>
<p id = "important-information">This paragraph needs to
be italicized and bolded!</p>

</body>
</html>
My to-do list needs more work. I'd like to highlight the most important tasks in yellow.
And I'd also like to cross out the tasks that I've already done. It should look something
like this:

You can accomplish this by using two class selectors. I called


mine highlight and done , but you could choose other names if you prefer.

The style declarations (rules) that you'll need are background-color:


yellow; and text-decoration: line-through; .

Start Workspace
Workspaces will shut down after 30 minutes of inactivity. Any running processes will
be stopped.
Start Workspace

Workspaces may take up to 5 minutes to start.


View Active Workspaces

## ⚠️Spoiler alert!

Our solution is below. You'll learn more effectively if you give the exercise a strong
effort before comparing your code with ours!
----

Solution
<style>
li {
font-size: 1.5em;
}
.highlight {
background-color: yellow;
}
.done {
text-decoration: line-through;
}
</style>
<h1>To-do:</h1>
<ul>
<li class="done">Buy milk
<li>Buy eggs
<li class="done">Buy flour
<li class="highlight">Make waffles
<li>Do laundry
<li class="highlight">Learn to code
<li class="highlight">Build a robot
</ul>
So now the important items on my to-do list are highlighted, and the completed items
are crossed out. But what if I want to have an item that is marked as both
important and completed? Like this:
In other words, how can we apply two classes to one element?

This turns out to be pretty easy---we simply put in both of the class names, separated
by a space. Like this:

<li class="highlight done">Make waffles</li>

You can give this a try in the workspace below.

Start Workspace

Workspaces will shut down after 30 minutes of inactivity. Any running processes will
be stopped.
Start Workspace
Workspaces may take up to 5 minutes to start.
View Active Workspaces

The power of separating style!


Let's do one more thing—I'd like the important list items to really stand out, so let's also
make them bold and red.

You can do that by simply adding a couple more declarations to the ruleset for
the highlight class:

.highlight {

background-color: yellow;

font-weight: bold;

color: red;

Give this a try in the workspace above!

Notice that if we were using inline styles, we would have to apply these changes on
every line of code with an li element. Here we only have seven—but you can imagine
how tedious this would get if we had a long list and needed to update the styles on
hundreds of list items!

Fortunately, because we have separated the style information, we can make the
changes in only one place (on the highlight ruleset) and they will automatically be
applied to all of the elements that have the highlight class. This is one of the things
that makes CSS so powerful!

Cascading and Specificity


The term "cascading" in Cascading Style Sheets refers to the way that style properties
"cascade" down the DOM tree, starting at the top. A style applied to the body element
will affect the entire document. A style applied to a lower-level element will affect that
element and all its descendants.

A style applied at a lower level can override a style at a higher level. For instance, if
the body has color: red but a paragraph within the body has color: blue, the
blue will apply to that paragraph and to any elements inside it:

<style>
body { color: red; }
p { color: blue; }
</style>
<body>
<p> This will be blue, not red. <br>
<em> Same with this. </em> </p>
</body>

Use the HTML below to answer the quizzes on this page!

<html>
<style>
body { font-style: italic; }
h1 { color: purple; }
body { color: green; }
p { color: orange; }
</style>
<body>
<h1> This is a very stylish document! </h1>
<h2> The styles are cascading </h2>
<p> So what color am I? </p>
</body>
</html>
Revisiting the div Element
In the video, you may have noticed that Kelly used the div element to create
the boxes. We looked briefly at the div element earlier, but it has been a
while—so, let's review the key ideas.

 It's used to divide up the page. The name div is short for division,
because that's what this element is for—you can use it to divide up the page
into different sections.
 It has an "invisible box" around it. Like the paragraph p element, the
division div element has an invisible box around it—and just like p , it can
have a border, a margin, a width, a height, and so on.
 It is a generic container. A p element is specifically meant to contain text. In
contrast, the div element is a generic container, meaning you can put
whatever other elements you want inside. You can use the div element to
organize the content and divide the page into sections.

The basic syntax is super simple:

<div>

</div>

And, we can texts inside the div, like this:

<div>

Example

</div>

And if we want to apply a style to a div, we can add a class attribute:

<div class="fancybox">

Example

</div>
And then, in our CSS, we can use a class selector with the same
name .fancybox to add whatever styling we want. Here's the example shown
in the video:

.fancybox{

border: 5px solid green;

margin: 1em;

padding: 0.5em;

width: 100px;

height: 50px;

float: right;

The div element is used all the time in HTML to structure web pages, so
you'll be seeing a lot more of it as you continue. On this page, we'll just be
using the div element to play around with boxes and adjust the margin,
padding, border, etc.
Let's add a second box. But let's make it small, and red. Let's also put some margin
around both boxes, so that they aren't mashed right up against each other.

Something like this:


Start Workspace

Workspaces will shut down after 30 minutes of inactivity. Any running processes will
be stopped.
Start Workspace

Workspaces may take up to 5 minutes to start.


View Active Workspaces

## ⚠️Spoiler alert!

Our solution is below. You'll learn more effectively if you give the exercise a strong
effort before comparing your code with ours!
----

Solution
<style>
.blue_box {
border: 10px solid blue;
padding: 0.5em;
margin: 0.5em;
width: 150px;
height: 100px;
}
.red_box {
border: 10px solid red;
padding: 0.5em;
margin: 0.5em;
width: 20px;
height: 20px;
}
</style>

<div class="blue_box">Hooray, a box!</div>


<div class="red_box"></div>
Some of the exercises on this page won't display correctly if you are working on a small
screen and have the left-hand classroom menu open as well (this makes the workspace
too small to see the boxes correctly).

If you're on a small screen, it may help to collapse the left-hand menu:


And if that doesn't give you enough space, you can also Expand the workspace:

Now let's try out the float property. To start with, just try adding float:
right; to the blue_box class.
Start Workspace

Workspaces will shut down after 30 minutes of inactivity. Any running processes will
be stopped.
Start Workspace

Workspaces may take up to 5 minutes to start.


View Active Workspaces

Your blue_box class should now look like this:

.blue_box {
border: 10px solid blue;
padding: 0.5em;
margin: 0.5em;
width: 150px;
height: 100px;
float: right;
}
Let's play with the boxes a little more.

If you recall, elements can have contents. Currently, only one of


our div elements has contents—the blue box contains the text Hooray, a
box!

But instead of using text for the contents, we could use the other box. To do
this, we simply have to nest the div for the red box inside the div for the
blue box (replacing the current contents Hooray, a box! ).

Like this:

<div class="blue_box">

<div class="red_box">

</div>

</div>
Interpreting percentages
Here is a piece of HTML with CSS. Use it to answer the question below!

<style>
.outer {
width: 300px;
border: 5px dotted orange;
}

.inner {
border: 5px solid blue;
width: 50%;
}
</style>
<div class="outer">
<p> This box has a box inside!
<div class="inner">
<p> How wide is the inner box,
<em>including</em> its border?
</div>
</div>

CSS Reference
You can find the MDN CSS reference here:

https://developer.mozilla.org/en-US/docs/Web/CSS/Reference

Stylesheet or style element — not both!


Note that you can put your CSS code inside of a <style></style> element, like this
...

<style>

p{color:blue;}
</style>

... or inside of a linked stylesheet, like we just talked about.

But you would not want to do both at the same time! In other words, when you place
your CSS in a stylesheet, you don't need to use a style element—you can just put
the CSS directly into the stylesheet with nothing around it:

p{color:blue;}

This is what you should do for the exercise below—simply put the CSS directly into
your style.css file (and don't use the style element).

Linking stylesheets
To link to a stylesheet in your HTML file, add a link element to the head of the
HTML file. The syntax for the link element is just like this:

<link rel="stylesheet" href="style.css">

If you are linking to a stylesheet located on another web server, you will use a full URL
in the href attribute. If you're linking to one that's in the same directory as your HTML
file, you can just use the filename as a relative URL.

Creating a CSS file


You might think that creating a CSS file requires something special, but all you have to
do is make a new text file (just plain old text!) and rename it with the extension .css .
This is similar to how we create our HTML files—they are simply text files that have
a .html file extension in the name.

For example, in the workspace below, you can hover over the plus button and
select New File—and then simply name the file styles.css .
Troubleshooting
When you first start using a separate CSS stylesheet, it is very common to have trouble
getting things to work.

If you have made both your .html file and your .css file and the styles just don't
seem to be showing up, you can try copying and pasting our code below into your files.

If our version works, you may have had a typo in yours.

The HTML file


Here's what the code in your HTML file might look like:

<head>

<link rel="stylesheet" href="style.css">

</head>

<p>

Here is an html file that you can use to experiment


with your styles.

</p>

The CSS file


And here is what your CSS file might look like:

p {color:purple; font-size:24;}

(Yes, your styles.css file can really contain just that one line and nothing else!)

Linking Trouble
If you still don't see the styles changing, it's probably not linked correctly. There are two
common mistakes that can happen with the link element.

Mismatched Names
The name of the file in the link element must match the way you named your CSS
file exactly. For instance, if you name your file style.css , but then link
to styles.css (with an s at the end of styles ), it will not look in the right location
to get the style info. The names must match exactly for the link to work.

In the gif below, we can see the names don't match and the styles are not showing up.
Once the name is fixed, it works perfectly.
Note that we don't have to call the file style.css specifically—we could call
it hippopotamus.css if we wanted to. It doesn't matter what we call the file, as long as
the names match. (But please only call it hippopotamus.css if you have a good
reason… 🦛)

Wrong Filepath
If the name is correct and it is still not working, check to make sure the HTML file and
the CSS file are in the same folder. In the gif below, style.css was created in a
separate folder, called My Folder so the styles are not showing up on the page. To fix
this, we can either move the file out of that folder or we can edit the path in
the link element to include the folder name, as in My Folder/style.css .
Practice: Three Ways to Style
LessonDownloads

At this point, we've learned three different ways to apply CSS styles to our HTML
elements. This can get a little confusing, so on this page we'll review all three
approaches. Try to notice what is different in each approach, and what is the same.

As we saw earlier, we can't put CSS code directly in our HTML, because then the
browser will think it is HTML. Instead, we have to have a way of signaling that the code
should be interpreted.

Question 1 of 5
Here's an attempt to apply a CSS style to some text:
color: blue;

<p>Hello!</p>

Will this work?

Yes—the text Hello! will be styled in blue.

No—the text Hello! will show up, but it won't be in blue.


Submit

Question 2 of 5
OK, so this code ...

color:blue;

<p>Hello!</p>

... doesn't work. But what actually happens when the browser tries to render this
page? (Feel free to try it out for yourself and see!)

It tries to apply the CSS style, but since there is no p selector, it doesn't know what to
apply the style to.
It interprets color:blue as text and displays it on the page, just like the
text Hello! .

It causes the page to fail (the page won't load in a browser until this is fixed).
Submit

Let's Fix It…


The next three quizzes all show attempts to fix the code we just looked at. Which of
these approaches would work and style Hello! in blue?

Question 3 of 5
First approach:

Use the style attribute, like this:

<p style="color:blue;">Hello!</p>

Does this approach work?

Yes, it works!
No, this is broken.
Submit

Question 4 of 5
Second approach:

Use the style element, like this:

<style>
p{color:blue;}
</style>

Yes, it works!

No, this is broken.


Submit

Question 5 of 5
Third approach:

Add a link element in our HTML file that points to a separate CSS file (also
called a stylesheet):

<link rel="stylesheet" href="style.css">


And then place this code in the CSS file:

p{color:blue;}

Yes, it works!

No, this is broken.


Submit

OK, now it's your turn! In the workspace below, you'll see that someone tried to apply
some styles to some text, but it's not working. See if you can fix it!

Try using all three of the approaches we just discussed, so that you can see them side-
by-side:

 Make the paragraph of text centered using the style attribute to apply
an inline style.
 Make the text blue using the style element with a type selector.
 Make the text big using a linked CSS file (stylesheet). Note that the stylesheet
has already been created for you, but you'll need to add the style to it, and
add the correct link element to your HTML.

Note: Of course, you would normally not use all three of these approaches at the same
time like this—this is just for practice.

Start Workspace

Workspaces will shut down after 30 minutes of inactivity. Any running processes will
be stopped.
Start Workspace

Workspaces may take up to 5 minutes to start.


View Active Workspaces

## ⚠️Spoiler alert!

Our solution is below. You'll learn more effectively if you give the exercise a strong
effort before comparing your code with ours!
----

Solution
The code in the HTML file should look like this:

<link rel="stylesheet" href="style.css">

<style>

p {color: blue;}

</style>

<p style="text-align: center;">Style me 3 ways!</p>

And the stylesheet ( style.css ) should look like this:

p {
font-size: 24pt;
In school, you may have learned that the primary colors are red, yellow, and
blue. But in the video, Kelly said they are red, green, and blue. What's up with
that?

It has to do with how we are mixing the colors. When we mix a material
like paint the physics of how the color will look behaves very differently from
when we mix together wavelengths of light (which is what we need to do when
lighting up pixels in a computer screen). If you're super curious, you can check
out this article about primary colors from How Stuff Works(opens in a new
tab).

But for these lessons, all you really need to remember is that computers
use RGB colors—that is, red, green, and blue.

Additional Resources
If you were extremely observant you may have noticed that at the end of the
video (above), Kelly mentions HSL color. We didn't mean to get into that
here, but if you're curious, HSL stands for Hue, Saturation, and Lightness. If
you like, you can check out the w3schools.com page on HSL color(opens in
a new tab). If you scroll down on the page, they even have a live example you
can play with to see how HSL colors work.
Kelly showed three different ways to represent color values in the code. For
example:

rgb(100%, 100%, 100%)

rgb(255, 255, 255)

#ffffff

Although they look different on the surface, they all work essentially the same
way.

In all cases, we need to give the amount (or you could say the intensity) of each
of the three primary colors: red, green, and blue (RGB).
We've been using the words "amount" and "intensity". What we really mean by this is
the brightness of the light. Higher values indicate brighter (more intense) light, and lower
values indicate darker (less intense) light.

By mixing different levels of red, green, and blue, we can get different colors, at different
levels of brightness.

By the way, this way of thinking about light isn't limited to our code—if we were to get
real, physical lights and overlap them, we would get similar results.
Red, green, and blue light overlap to create secondary colors and white light.
(Public domain image from Wikimedia Commons(opens in a new tab))

In the image above, notice that if we mix equal (and intense) levels of all three colors,
we get white light. And you can probably imagine that if we lowered the intensity of all
three colors by equal amounts, we would get various shades of gray.

OK, but what about hex values, like #00cc66 or #99ccff ?

These look strange, but they work the same way. Each pair of digits is a
number that gives the intensity of red, green, or blue. The reason these values
look strange is because they're in a different number system—instead of
the decimal(opens in a new tab) system that we are used to working with,
these numbers are given in the hexadecimal(opens in a new tab) system.

You don't need to have a deep familiarity with hexadecimal to be able to use
hex color values on your pages—but we'll briefly explain the basics so that
you can get a feeling for how they work.

Hexadecimal is not as complex as it might appear. Instead of having 10 digits


(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), hexadecimal has 16. Since we don't have 16
number symbols, hexadecimal counts up to 9 and then starts using letters.

Here is how we would show the numbers 0-15 in decimal and hexadecimal:
| Decimal | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
|---|---|---|---|---| | Hex | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |

Notice that it's the same until we get to 10, which is represented as A in
hexadecimal.

Like we mentioned, each pair of digits in a hex RGB value gives the intensity
of red, green, or blue. This ranges from 00 , meaning zero intensity, to ff ,
meaning maximum intensity. In fact, the number ff is the same as the
decimal number 255 .

This may seem very alien, but take a try at the following exercise—just to get
a feeling for how hex values work.

Practice: Searching for Properties


LessonDownloads

There are so many CSS properties out there, it's difficult to know (or remember) them
all! And even if you do remember the property you want, you may not be able to recall
the exact syntax. (Was it text-align: center; or text-align: centered; ?

Even experienced developers don't have every single property memorized. Fortunately,
it's usually easy to find what you need by looking it up in the documentation or using
your favorite search engine.

Most of the time, you can simply type in "CSS", followed by some words related to the
property. For example, if you want to know how to set the background color, searching
for "css background color" will turn up the results you're looking for.

And as we've mentioned previously, the Mozilla Developer Network(opens in a new


tab) is a good resource to keep in mind (it also has a search option you can check out).
Use the Mozilla documentation or your favorite search engine to find the CSS property
for setting an element's background color.

Once you find it, type the property in below:


Submit

Suppose you have a list, such as:

 First thing
 Second thing

And you want to change the style of the list (for example, to use square bullets instead
of round ones). What CSS property could you use?

Submit

Font vs Typeface
If you have worked in a word processor (like Microsoft Word, for example), you may
have seen things like Times New Roman, Courier, Arial, or Helvetica. For example:

This Text is in Times New Roman

In word processors (and everyday speech) we would call this the "Times New Roman
font". But technically, "Times New Roman" is not a font—it is a typeface.

Wait, what?

Most typefaces have multiple versions that look a little different from one another. For
example, we have:

Times New Roman italic

And also:

Times New Roman bold


These are all examples of the same typeface. but each one is a different version
or font.

A typeface is a group of related fonts.


A font is a specific version of a typeface.

Font Families
Another term we can use for a typeface (or group of related fonts) is a font family.
That's the term that CSS uses.

In other words, to change the typeface of our text, we can use the font-
family property. Like this:

font-family: Helvetica;

Or here's another example:

font-family: "Times New Roman";

Note: You might notice that one of these has quotes " " while the other does not. The
quotes are recommended for font families that have spaces in the name. They help
ensure that the name is read as one thing ( "Times New Roman" ), rather than potentially
three separate things ( Times , New , and Roman ). The spaces don't usually cause a
problem, so this is a recommended practice, not a requirement (you can leave them off
and it will typically still work).

Generic Font Families and Font Stacks


Sometimes we don't care about the specific font family, but we do need the text to use a
general kind of font family. For this, we can use generic font families.

Monospace as an Example
Compare these three examples:
This is an example
This is an example
This is an example
Each of these uses a different font family (or typeface). If you're curious, they
are Courier, Courier New, and Source Code Pro.

Even though they are different font families, they are all examples of monospace font
families. In a monospace font family, every character is the same width—so, for
instance, these two letters are the same width:

i
m
Monospace font families are really useful for writing code because they ensure that
everything lines up exactly as expected:

This is 27 characters long! And this is the


same length
We would not want to be writing our HTML or CSS and have different bits of our code
be different lengths depending on which letters are in that part of the code!

So if we were putting some code on a web page, we might not care exactly what font
family it uses, but we would want to make sure it is some kind of monospace.

Generic Font Families


That's where generic font families come in. There are five, each named for a general
kind of typeface:

 Serif
 Sans-serif
 Cursive
 Fantasy
 Monospace

In CSS, we can use a generic font family in place of a specific font family. For example,
this line specifies the specific font family Courier:

font-family: Courier;

In contrast, this one simply says to use whatever monospace font family is available

font-family: monospace;

Font Stacks
Since we don't know what font will be available to each user, it's a good idea to give
multiple options. CSS allows us to do this by using a font stack, like this:

font-family: Courier, "Courier New";

As you can see, we simply list the font families that are OK to use, with the most-
preferred choice first. If that choice isn't available, it will try the next one, and so on.

A common (and very good) practice is to put the generic font family at the end of the list,
like this:

font-family: Courier, "Courier New", monospace;

This way, if none of the other font families are available, the browser will still use the
right general type.

Task List

Go ahead and add a font-family property to the p selector in the stylesheet.


Include a stack of at least three font families.

Use a generic font family for the last one in the stack.

Start Workspace

Workspaces will shut down after 30 minutes of inactivity. Any running processes will
be stopped.
Start Workspace

Workspaces may take up to 5 minutes to start.


View Active Workspaces

### ⚠️Spoiler alert!

Our solution is below. You'll learn more effectively if you give the exercise a strong
effort before comparing your code with ours!
----

There are many different font families you can use. Here are a few different examples of
what your CSS file might look like. Each one provides a couple of specific font families
and then ends with the relevant generic font family:

Monospace:

p{

font-family: "Courier New", Courier, monospace;

}
Serif:

p{

font-family: Times, "Times New Roman", serif;

Sans-serif:

p {
font-family: Verdana, Helvetica, sans-serif;
}

Additional Resources
 If you're curious to learn more, you can find additional details and some
interactive examples in the MDN Web Docs on the font-family
property(opens in a new tab).
 When you need to know what font families to use in a stack, you can check
out cssfontstack.com(opens in a new tab). When you click on a font family, it
will tell you what other fonts you might want to put in the same stack, and it
even shows the CSS you would use for each one.

In addition to the font family, there are a bunch of other properties we can use
to style our text.

Font Size
To change the font size, we can use the font-size property, like this:

font-size: 24px;

In this example, px stands for pixels.


Bold
To make the text bold, we can use the font-weight property, as in:

font-weight: bold;

Italic
To make the text italic, we can use the font-style property:

font-style: italic;

Underline
To make the text underlined, we can use the text-decoration property:

text-decoration: underline

Font Shorthand
LessonDownloads

The Shorthand font Property


It can get a bit tedious typing all the different properties out individually. Fortunately,
there is a shorthand way to do this by using the font property.

For example, instead of typing out:

font-style: italic;

font-size: 24px;

font-family: Times;

We can simply use:

font: italic 24px Times;


We simply list the values, with a space in between each.

…but it has to be in the right order


Like Karl mentioned at the end of the video, the downside to the shorthand is
that things need to be listed in a specific order, and it's kind of easy to forget
what that order is. Here are all the properties you can set using
the font shorthand and the order in which you would specify them:

1. font-style
2. font-variant

3. font-weight

4. font-size

5. font-family

Or to put that in context:

font: font-style font-variant font-weight font-size font-


family;

Here's an example that uses all five properties:

font: italic small-caps bold 24px "Times New Roman";

If you're able to memorize that, great! If not, you can do what Karl does and
just look it up when you need it. You can find it in this CSS-TRICKS
article(opens in a new tab) , listed near the top of the CSS font property
documentation from W3Schools(opens in a new tab) —or simply Google "font
shorthand order".
Wait, what if I leave something out?
There are two properties that are required when you use
the font shorthand: font-size and font-family . Everything else is optional. If
you leave out one of the optional properties, it will just use the default.

For example, this specifies the font-style :

font: italic 24px Times;

But this one leaves it out:

font: 24px Times;

Since the font-style isn't specified, it defaults to normal (i.e., not italic).

Key Points About the font Shorthand

So, to summarize the three key points you need to remember:

 Font size and font family are required


 Things need to go in the right order
 If you leave an optional property out, it will use the default
 Earlier, we saw that we could put boxes inside other boxes. If those
boxes are div elements, then we simply nest the div elements inside
one another:
 <div>

 <div>

 </div>

 </div>

 One reason to nest boxes like this is so that you can use one of the
boxes as a container for the other boxes. To get an idea of why this
would be useful, let's take a look at an example.
 In the workspace below, you'll find three boxes stacked vertically (notice
that they're currently not inside a container). You'll also see that there's
a linked stylesheet, and that we've styled the boxes using some different
classes.
 Suppose that we want to get all three of the boxes to stay in a vertical
stack, but move over to the right side. How can we do this?
 Well, first let's try this: Add float:right; to the .box class, so that the
boxes float on the right side of the page. Then answer the questions
after the workspace.
 OK, so trying to float the boxes on the right individually didn't do what
we wanted—they ended up in a horizontal row, rather than staying in a
vertical stack.
 To solve this, we can put the three boxes inside a fourth box. By
wrapping them in a container like this, we can then move the container
around without changing the arrangement of the boxes inside.
 Code for containers.html:
 <!DOCTYPE html>

 <html lang="en">

 <head>

 <meta charset="utf-8">

 <title>Containers</title>

 <link rel="stylesheet"
href="containers_style.css">

 </head>

 <body>

 <div class="container">

 <div class="box red">red</div>

 <div class="box green">green</div>

 <div class="box yellow">yellow</div>


 </div>

 </body>

 </html>

 Code for containers_style.css:


 .container{
 float: right;
 }

 .box{
 width: 100px;
 height: 100px;
 text-align: center;
 font-size: 30px;
 font-weight: bold;
 font-family: sans-serif;
 }

 .red{
 background-color: red;
 }

 .green{
 background-color: green;
 }

 .yellow{
 background-color: yellow;
 }
 In the workspace below, you'll find all of the code that Kelly started with
in the video. Go ahead and try applying the two flexbox properties that
Kelly demonstrated ( display and flex-wrap ).
 Note that these get added to the container element, not the inner boxes.
 You should end up with a horizontal row of boxes that wraps when the
browser window is resized.
 In case you're having trouble and need to troubleshoot, here's Kelly's full CSS
code:
 .container{
 width: 100%;
 display: flex;
 flex-wrap: wrap;
 }

 .box{
 width: 100px;
 height: 100px;
 text-align: center;
 font-size: 30px;
 font-weight: bold;
 font-family: sans-serif;
 }

 .red{
 background-color: red;
 }

 .green{
 background-color: green;
 }

 .yellow{
 background-color: yellow;
 }

 Additional Resources
 It's not required for this course, but if you want to understand the concepts and
options in more detail, you may enjoy reading this documentation from Mozilla
for the flexible box layout (aka "flexbox")(opens in a new tab) . This is pretty
advanced, so don't be surprised if you find it challenging. If you want to, you can
play with the workspace above (or one of your local HTML files if you're
experimenting on your own computer) to see what you can do. For example, can
you use the documentation to figure out how to write flexbox code that results in
a two-column layout?
 When using flexbox, it's important to understand how the size of the container
element affects the layout of the boxes that are inside of it.
 You may have noticed that in Kelly's code, the width of the .container class is
set to 100% . That means the container will be as wide as whatever it's inside—
in this case, the container is inside the body element of the page, so it will take
up the full width of the page.
 To see this more easily, we can add a border to the container class.
 In the workspace below, add border: 5px solid black to the .container class.

 Start Workspace

 Workspaces will shut down after 30 minutes of inactivity. Any running


processes will be stopped.
 Start Workspace

 Workspaces may take up to 5 minutes to start.


 View Active Workspaces

 Now that we can see the size of the container element, let's try changing the
width.

 Quiz Question
 Currently the width is set to 100%. Try changing it to 200 pixels ( 200px ).
What happens?
 ⚠️Make sure you enter 200px and not just 200 . If you leave off
the px you'll get very different results!


 The first two boxes stay where they are, but the third box wraps to the second
line.

 All three boxes stay where they are (in a single horizontal line).

 All three boxes stay where they are (in a single horizontal line) and resize
(becoming narrower).
 Submit

 In case you need it, here's the full CSS code with the changes we just made:
 .container{
 width: 200px;
 display: flex;
 flex-wrap: wrap;
 border: 5px solid black;
 }

 .box{
 width: 100px;
 height: 100px;
 text-align: center;
 font-size: 30px;
 font-weight: bold;
 font-family: sans-serif;
 }

 .red{
 background-color: red;
 }

 .green{
 background-color: green;
 }

 .yellow{
 background-color: yellow;
 }
 Let's get some more practice with flexbox. Your job here is to replicate this
checkerboard design:

 We've given you a little starter code, but it's up to you to create all the boxes and
add the correct CSS.
 This is very similar to the code we just went over on the last page, so if you get
stuck you can always look back at that (or check out our solution code below).

 Start Workspace


 Workspaces will shut down after 30 minutes of inactivity. Any running
processes will be stopped.
 Start Workspace

 Workspaces may take up to 5 minutes to start.


 View Active Workspaces
 ## ⚠️Spoiler alert!

 Our solution is below. You'll learn more effectively if you give the exercise a
strong effort before comparing your code with ours!
 ----

 Solution
 Code for flexbox_practice.html:
 <!DOCTYPE html>

 <html lang="en">

 <head>

 <meta charset="utf-8">

 <title>Flexbox practice!</title>

 <link rel="stylesheet" href="flexbox_practice_style.css">

 </head>

 <body>

 <div class="container">

 <div class="box red"></div>

 <div class="box black"></div>

 <div class="box black"></div>

 <div class="box red"></div>


 </div>

 </body>

 </html>

 Code for flexbox_practice_style.css:


 .container{
 width: 200px;
 border: 5px solid black;
 display: flex;
 flex-wrap: wrap;
 }

 .box{
 width: 100px;
 height: 100px;
 }

 .red{
 background-color: red;
 }

 .black{
 background-color: black;
 }
 We've gone over a ton of CSS syntax in this section, and we know it can be hard
to remember it all! This page provides a review that you can refer to as needed. If
you like, you can also download a PDF version of this page to refer to later,
such as when you're working on your final project (opens in a new tab) .

 Ruleset Syntax
 The basic syntax of a CSS ruleset has two parts: a selector, and a group of rules,
each of which consists of a property name and the value of that property.
 selector {

 property: value;

 }
 The selector is written first, and then the rules are written inside { curly
brackets } . Each rule's property and value are separated by a : colon, and the
rule always ends with a ; semicolon.

 Selectors
 The selector indicates which HTML elements the rule will apply to. You've seen a
few different sorts of selector: the element selector, the class selector,
the id selector, and the descendant selector.
 A type selector applies to every HTML element of a particular type, such
as p or em . This selector will apply to every p element:
 p {

 color: blue;

 }

 A class selector applies to all elements that share a class attribute. The class
selector is written starting with a . (dot):
 .narrow {

 width: 20%;

 }

 In order for the class selector to apply, there have to be HTML elements on the
page that use that class attribute:
 <div class="narrow">

 This will get the 20% width.

 </div>

 An id selector applies to an element with a particular id attribute. The id


selector is written starting with a # sign:
 #sidebar {
 background-color: lightgray;

 width: 20%;

 float: left;

 }

 Within an HTML page, there should be only one element with that id attribute
value.
 <div id="sidebar">

 This will get the background, width, and float


values from the sidebar CSS rule.

 </div>

 A descendant selector is a compound of two simpler selectors. It applies only to


an inner element that is a descendant (on the DOM tree) of a particular outer
element.
 li a {

 color: pink;

 }

 The above selector will apply to a elements (hyperlinks), but only those inside
an li element (list item):
 <ul>

 <li> <a href="https://www.udacity.com/"> Pink


Udacity </a>

 </ul>

 <p> <a href="https://www.google.com/"> Non-pink


Google </a>

 Rules
 A ruleset can be composed of several rules, each of which applies a
particular value to a property of the selected elements. Properties are things
such as the color, position, size, and shape of the element.
 h1 { color: red; font-size: larger; }

 This rule applies the value red to the property color , and the value larger to
the property font-size .
 Some properties allow values that are more than one word long, such as
the font property:
 body { font: 12pt bold Consolas, Monaco, monospace; }

 Font stacks
 The font-family and font properties allow you to specify a font stack, a list of
font options separated by , commas. The browser will use the first font in the
stack that is available on the user's system. Usually the last font in the stack
should be a generic font name, such as serif , sans-serif , or monospace .

 Colors
 There are several ways to specify a color in CSS. Three common ones are hex
codes, rgb triples, and color names.
 .orange {

 color: #ff9900;

 }

 .pink {

 color: rgb(100%, 80%, 80%);

 }

 .chartreuse {

 color: chartreuse;
 }

 Flexbox
 To change the browser's layout from the default document-based layout to the
flexible box layout, set display: flex on a container element (one that has other
elements inside it).
 .outer {

 display: flex;

 border: 2px dotted orange;

 }

 .inner {

 width: 100px;

 border: 1px solid black;

 padding: 10px;

 }

 Flexbox can be heavily customized! The above will cause .inner HTML elements
to be packed in a row within the .outer element:
 <div class="outer">

 <p class="inner"> I am a box. </p>

 <p class="inner"> I am another box. </p>

 <p class="inner"> Hey, I am a box, too! Boxes


<strong>rock</strong>. </p>

 <p class="inner"> Let's be boxes together. Yay,


flexbox. </p>
 </div>

 I am a box.
 I am another box.
 Hey, I am a box, too! Boxes rock.
 Let's be boxes together. Yay, flexbox.

 In this last part of the lesson, we're presenting you with a challenge very similar
to what a real web developer might encounter: You'll be given a design and
asked to apply your new CSS skills to reproduce it.
 This exercise is definitely harder than anything else we've done in this lesson!
We encourage you to give it a try and really experiment with your CSS to see if
you can get the desired result—but also we don't want you to get stuck or
discouraged.
 Kelly and Karl each provide full solutions on the next page, so regardless of
whether you solve it or only get part way there, you should move ahead and
check out how they approached it.
In the workspace below, try replicating the design of the tic-tac-toe board
shown in the video. There's also a copy of the image below the workspace.

To do this, you'll only need to add CSS rules to the file tictactoe.css. (You
don't need to edit the HTML file at all!)

Here are a few hints:

 The ul and the li elements have boxes just like the div elements we've been
working with. And you can think about the ul as a container for the li elements.
 Like Karl said in the video, you will probably run into a couple of places where
you need to look up CSS properties you haven't encountered before. For
example, you'll need some way of hiding the bullets in the bulleted list. (Karl
had to look that up too when he solved the challenge.) Google is your friend
here!
 As with most problems in computer science, there's more than one way to solve
this! We feel this is an important idea, so we've included both Karl's approach
and Kelly's solution as well.

 Karl's Solution
 Show TranscriptSummarize Video

 And here's Karl's code:


 ul{
 width: 300px;
 height: 300px;
 display: flex;
 flex-wrap: wrap;
 }

 li {
 width: 90px;
 height: 90px;
 font-size: 80px;
 font-family: sans-serif;
 background-color: lightblue;
 margin: 5px;
 list-style: none;
 text-align: center;
 }

 Kelly's Solution
 Note: In this next video, the code editor shows font-size: 40px , but Kelly's code
should actually have said font-size: 80px (the 40px font is too small and won't
appear to be vertically centered).
 Show TranscriptSummarize Video

 And here's Kelly's code:


 ul{
 width: 300px;
 height: 300px;
 }

 li {
 width: 90px;
 height: 90px;
 margin: 5px;
 float: left;
 list-style: none;
 font-size: 80px;
 font-family: sans-serif;
 text-align: center;
 background-color: lightblue;

 }

Congratulations!
If you've made it this far, then you've picked up some genuinely challenging
concepts, including some ideas—like tree structures—that you would be
learning if you were enrolled in a university-level Computer Science (CS)
curriculum.

By learning CSS and HTML, you've picked up some very practical web
development skills, such as how to:

 Define the structure and content of a web page with HTML


 Add style to a page using CSS
 Tell the difference between CSS syntax and HTML syntax, while using the two
side-by-side
 Identify exactly what each part of the code does (such as what an HTML
element is and how it works)
 Use developer tools to look into the inner workings of real, live web sites
 Debug or troubleshoot your code when things go wrong
You now have everything you need to make simple—but fully functional and
fully styled—web pages! We think that makes your brain quite a bit more
awesome than it was when you started, and we hope you feel the same. 🧠🤩

A Note About Udacity Projects


At Udacity, we believe in hands-on learning. We believe the best way to both
practice and demonstrate your skills is to use them to solve a real-world
problem.

Along those lines, the final project for this course (coming up next) is how
you'll demonstrate that you really know how to use the tools you've just
learned about. Can you use HTML and CSS to actually make a thing? That is
the real test!

But don't worry, you can't fail this test. When you submit your project, a
Udacity reviewer will check it over carefully. If something isn't quite right,
they'll mark it as Requires Changes ❌ and leave you some helpful comments
so you know what needs to be changed.

Once it all looks good, they'll mark it as Meets Specifications ✅ and you will
have officially passed the course!

So with all of that in mind, we encourage you to just jump in and have fun with
it! And if you don't pass the first time (or second or third time!), don't feel bad
and don't give up—just check out what your reviewer has told you and use
their feedback as an opportunity to get better and grow your new skills. 🌱

Intro to JavaScript
LessonDownloads

Show TranscriptSummarize Video


Meet Julia and James!
We'll be your instructors for this introductory course on JavaScript.

JavaScript was Created for the Web


JavaScript was created in 1995 to make it easier to add interactive and dynamic
elements to websites.

Today, JavaScript is used for all sorts of applications - from programming robots to
writing game scripts. Even some code editors were built with JavaScript.

What You Will Learn


In this course, you'll learn the foundations of the JavaScript programming language,
from the history of JavaScript to how to:

 Run JavaScript code in the console of your web browser


 Create variables and use basic JavaScript data types to represent real-world
data
 Use conditionals to add logic to your JavaScript programs.
 Create loops to reduce code duplication and add automation
 Write functions to streamline and organize your code.
 Use arrays to store and manipulate lists of data.
 Use objects for even more complex data organization

If you're familiar with using HTML and CSS to create web pages, JavaScript is the final
piece you'll need to make your websites come to life!

Prerequisites
There are no prerequisites for this course.
Where Did JavaScript Come From?
The first version of JavaScript was created in just ten days 1995 by Brendan
Eich(opens in a new tab) . Eich was working on Netscape Navigator, one of the
Internet's first web browsers. Eich's goal was to add the capability for dynamic web
pages, which, at that time, were simple pages of HTML and CSS.

Why Is It Called Javascript?


JavaScript was originally called LiveScript, but it was changed back to JavaScript as a
marketing decision to piggyback off Java's popularity. Despite the name, JavaScript is
not related to Java in any way.

The Evolution of JavaScript


As the language evolved, competing versions of the language emerged. To standardize
the language, JavaScript was brought to Ecma International(opens in a new tab) , an
industry association "dedicated to the standardization of information and communication
systems." That's why you might hear JavaScript referred to as ECMAScript.

The standards body has transitioned to a year-based number to promote a more


consistent release cycle. So we have ES2016, ES2017, and so on. You can see current
specifications on the ECMA website. ECMA-262(opens in a new tab) , and you can
even look over drafts of proposed updates ECMAScript® 2022 Language
Specification(opens in a new tab)

JavaScript Today
JavaScript has grown to be one of the most popular programming languages globally
and is considered one of the foundational pillars of front-end web development.

You can read more about the current standards for JavaScript in MDN Web Docs:
JavaScript(opens in a new tab)
Want to Learn More?
Read a little history of JavaScript in Wikipedia(opens in a new tab) .
TIP: HTML and CSS are markup languages*. Markup languages are used to describe
and define elements within a document. JavaScript is a* programming language*.
Programming languages are used to communicate instructions to a machine.
Programming languages can be used to control the behavior of a machine and to
express algorithms.*

Using the JavaScript Console in Google Chrome


Note You can find instructions on how to access developer tools in other browsers on
the next page.

1. Open Developer Tools: Right-click on the page and select Inspect.


2. Open the Console: Click on the Console tab or use a shortcut
(Cmd+Option+J on macOS or Ctrl+Shift+J on Windows)
3. Write your code!: Here are some examples. Either type this into the browser
or copy it and paste the code into the console. Don't forget to hit return to run
the code.

"Julia"

alert("Hello, Julia! How are you?!");

Writing code in the console is a great way to test out simple bits of code, but
as your code gets larger the browser user interface can be awkward. We
recommend using a text editor like VSCode(opens in a new tab) , Atom(opens
in a new tab) , or Sublime Text(opens in a new tab) to write your code and
pasting your code in the console when you're ready to run it.

We'll also provide workspaces for the quizzes and activities in this course.

Want to Learn More?


Learn about Chrome Dev Tools Keyboard Shortcuts(opens in a new tab) to
help you move around in the console more quickly.

Developer tools on different browsers


Did you know that every modern web browser includes its own set of
developer tools?

If you didn't, that's okay. Developer tools aren't always the easiest thing to find
in your browser. So, we've decided to help you out by creating this guide to
developer tools!

Google Chrome
The Chrome DevTools are a set of web authoring and debugging tools built
into Google Chrome. Use the DevTools to iterate, debug and profile your
site. Learn more about Chrome DevTools here(opens in a new tab) .

To open Chrome DevTools, either right-click on any page element and


select Inspect or open the Chrome settings menu in the top-right corner of
your browser window and select More Tools > Developer Tools . Alternatively,
you can use the shortcuts:

 Command + Option + i (Mac)


 Ctrl + Shift + i (Windows/Linux).

Mozilla Firefox
Firefox Developer Tools allow you to examine, edit, and debug HTML, CSS,
and JavaScript on the desktop and mobile. Also, you can download a version
of Firefox called Firefox Developer Edition(opens in a new tab) , which is
tailored for developers, featuring the latest Firefox features and experimental
developer tools. Learn more about Mozilla Firefox DevTools here(opens in
a new tab).
To open Firefox Developer Tools, either right-click on any page element and
select Inspect Element or open the Firefox settings menu in the top-right
corner of your browser window and select Developer . Alternatively, you can
use the shortcuts:

 Command + Option + i (Mac)


 Ctrl + Shift + i (Windows/Linux).

Microsoft Edge
Microsoft Edge introduced great new improvements to the F12 developer
tools seen in Internet Explorer. The new tools are built in TypeScript and are
always running, so no reloads are required. In addition, F12 developer tools
documentation is now fully available on GitHub(opens in a new tab) .

To open developer tools in Microsoft Edge, simply press F12 .

Learn more about Microsoft Edge DevTools here(opens in a new tab) .

Safari
For any Mac users, Safari includes Web Inspector, a powerful tool that makes
it easy to modify, debug, and optimize a website for peak performance and
compatibility on both platforms. Learn more about Safari Web Inspector
here(opens in a new tab) .

To access Safari's Web Development Tools, enable the Develop menu in


Safari’s Advanced preferences. Once enabled, you can right-click on any
page element and select Inspect Element to open Web Development Tools
or use the shortcut Command + Option + i .

Opera
Opera is a fast, lean, and powerful web browser. You can open Developer
tools in Opera using the following keyboard shortcuts:
 Command + Option + i (Mac)
 Ctrl + Shift + i (Windows/Linux).

Alternatively, you can target a specific element by right-clicking on the page


and selecting Inspect Element .

The Console Is Your Coding Sandbox


The console is a great place to mess around with your code without any long-term
consequences. The console will tell you if there are any warnings or errors on the page,
display any output, or print it with console.log .

Using console.log statements


console.log is used to display content to the JavaScript console. Run the following
code in the console:

console.log("hiya friend!");

Prints: "hiya friend!"


This can be very helpful in figuring out what is going on when you are debugging your
code.

NOTE: You may see some errors or warnings in the console from the site you're visiting
-- and that's okay! Warnings are very common and will not affect the code you write in
this course.

Troubleshooting
For Chrome users, if you don't see the output, click “Default levels” in the console and
make sure that "Info" is checked. Congratulations! You performed the log action on
the debugging console .

The message you’ve logged is "hiya friend!". hiya friend! is a string (a sequence of
characters).
Give It a Try!
Let’s use console.log to do something a little more interesting. Here’s a block of
JavaScript code that loops through the numbers 0 through 9 and prints them out to the
console:

for (var i = 0; i < 10; i++) {

console.log(i);

Prints:
0
1
2
3
4
5
6
7
8
9
This is called a loop.

Based on this loop's settings, any code written inside the curly brackets {...} will be
repeated ten times. In this case, console.log prints out the value of i each time the
loop runs. Don't worry if you're not sure about what the syntax means at this point. Later
in this course, you will learn more about how and when to use loops.
console.log Demo

Other console methods

Browser console has other methods that can be very useful when poking around. For
example, try typing console.table(["orange", "strawberry", "banana"]) in the
console. This method will create a table and display the data in it.

You are welcome to explore the console.dir method on your own. Don't be afraid to
tinker!

For more information you can also refer to MDN documentation: console(opens in a
new tab).
JavaScript demo
So you saw how to use console.log to print a message to the JavaScript
console. Now, let’s see how you can use the console as a sandbox to test a
new line of JavaScript in the browser.

Open the Daring Fireball website(opens in a new tab) in a new tab and in that
tab also open up developer tools. Then paste the following code:

document.getElementsByTagName("h1")[0].style.color =
"#ff0000";

NOTE: If you can't access https://daringfireball.net/(opens in a new tab), try a


different website like https://www.udacity.com/(opens in a new tab). This demo will
work on many different websites.

Build an eCommerce Shopping Cart


By the end of this course, you will understand enough JavaScript to build a fully
functioning eCommerce shopping cart for Kirana's Fruit Stand.

We'll provide the front end, which looks like this:


Completed Storefront
and you will write the code that makes it work.

You will create:

1. A list of products that users can buy


2. Functions to enable typical shopping cart functions including:
 Adding an item to a cart
 Increasing or decreasing the quantity of an item

 Removing an item
 Adding up the cost of all items in the cart
 Paying for the items

The code to connect your products and functions will also be supplied, so you only need
to focus on the JavaScript code.

Why This Project?


Our goal is to challenge you to think like a programmer and use the skills you will learn
in this course. This project barely touches the surface of what is possible, but it does
use many of the foundational skills that will make up the majority of most of your future
coding projects.

What We've Learned So Far


We've covered a lot already! You have:

 Learned that all major browsers come with built-in JavaScript engines that
allow browsers to run and execute JavaScript code.
 Practiced running JavaScript code in the browser console
 Added styles to a webpage just by running code in the console

We hope you are beginning to see the power of JavaScript, and you are ready
to dive in and explore the language.

See you in the next lesson!


Data is Everywhere!

All of these things can be represented as data:

 The grade you received on your first math test.


 The conversation you had earlier today.
 The decision you made to sit down and watch this video.
 And more...

Data is Important
It helps us:

 Understand the world


 Recognize trends
 Make educated guesses and
 Inform our decisions

Data and data types are the building blocks of any programming language
because they help us organize information and determine how our programs
will run.

In this lesson we will learn how to define and manipulate the primitive data
types of JavaScript.

 numbers
 strings
 booleans
 undefined

 null

Once you're familiar with these data types, you'll see how you can store data
in variables that you can reuse to manipulate data with your code.
Numbers
Defining a number in JavaScript is actually pretty simple. The Number data type
includes any positive or negative integer, as well as decimals. Entering a number into
the console will return it right back to you.

Returns: 3
There, you did it.

Arithmetic operations
You can also perform calculations with numbers pretty easily. Basically, type out an
expression the way you would type it in a calculator.

3 + 2.1

Returns: 5.1

Arithmetic Operators in JavaScript


Name Operator Meaning

Addition a+b Adds a and b

Subtraction a-b Subtracts b from a

Multiplication a*b Multiplies a and b

Division a/b Divides a by b


Name Operator Meaning

Modulo a%b Returns the remainder of a / b

Exponent a ** b Raises a to the power of b

The Modulo Operator


You are probably familiar with the basic operators, but you might not have seen
the % operator yet.

We use the modulo operator to return the remainder of a division operation. This can be
very helpful in a lot of programming tasks.

Before we move on, let's do some modulo practice.

Comparison Operators
Operator Meaning

< Less than

> Greater than

<= Less than or Equal to

>= Greater than or Equal to

== Equal to

!= Not Equal to
TIP: The values true and false have significant importance in JavaScript. These values are
called Booleans and are another data type in JavaScript. Later in this lesson, you’ll learn more
about why Booleans are so important in programming.

// You're about to take your first programming quiz!

Before you move onto the quiz, we want to talk about something you'll see
quite often throughout this course: comments!

You can use comments to help explain your code and make things clearer. In
JavaScript, comments are marked with a double forward-slash // . Anything
written on the same line after the // will not be executed or displayed. To have
the comment span multiple lines, mark the start of your comment with a
forward-slash and star, and then enclose your comment inside a star and
forward-slash / *…* / .

// this is a single-line comment

/*

this is

a multi-line

comment

*/

Some of the quizzes in this course might include comments that give you hints
or instructions to complete the quiz. Pay attention to those comments!

You may see comments that are used to clarify and document complex code.
This may improve readability, but it often makes more sense to reduce the
complexity by refactoring and simplifying the code. Simpler code is often
better code.

Alright, good luck!


Directions:
In the first-expressions.js file in the code editor below, write an expression that:

 uses at least 3 different arithmetic operators.


 equals 42 .

Hint: + , - , * , / ,* and % are possible arithmetic operators*

Running Your Code


Enter the following in the terminal:

node first-expression.js

Node.js(opens in a new tab) is an open-source backend JavaScript runtime


environment. That basically means that it will run your JavaScript code in the terminal
and return any output that is generated. We'll be using Node to run the code in our
workspaces for many of the quizzes in this course.

⚠️These workspaces will autosave your code -- but it can take a few seconds.
If you try to run your code before the autosave occurs, you will see an error like this:
ReferenceError: Cannot access 'variableName' before initialization
Wait a few seconds and try to run the code again.

Start Workspace

Workspaces will shut down after 30 minutes of inactivity. Any running processes will
be stopped.
Start Workspace

Workspaces may take up to 5 minutes to start.


View Active Workspaces
Try the quiz on your own first. If you get stuck you can check the solution by clicking the
button below.

Show Solution

Key Points to Remember About Strings


 Strings can be any combination of characters -- letters, numbers and even
emojis
 You must use matching quotes at the beginning or end of the string --
otherwise JavaScript thinks you are referring to a variable

TIP: It is correct to either use double " or single ' quotes with strings, as long as you're
consistent. The JavaScript Udacity style guide(opens in a new tab) for labs and
projects suggests using single quotes to define string literals -- but your team or
organization might follow a different style guide and prefer double quotes.
Always follow your team's style guide

String concatenation
Strings are a collection of characters enclosed inside double or single quotes.
You can use strings to represent data like sentences, names, addresses, and
more. Did you know you can even add strings together? In JavaScript, this is
called concatenating. Concatenating two strings together is actually pretty
simple!

"Hello," + " New York City"

Returns: "Hello, New York City"


You will see other ways to concatenate and do even more with strings later in
this course. But for now, practice using the addition + operator.

Variables Allow Us to Store Data!


With variables, you no longer need to work with one-time-use data.
At the beginning of this course, you declared the value of a string, but you didn't have a
way to access or reuse the string later.

"Hello"; // Here's a String "Hello"

"Hello" + " World"; // Here's a new String (also with the


value "Hello") concatenated with " World"

Storing the value of a string in a variable is like packing it away for later use.

var greeting = "Hello";

Now, if you want to use "Hello" in a variety of sentences, you don't need to duplicate
"Hello" strings. You can just reuse the greeting variable.

greeting + " World!";

Returns: Hello World!


greeting + " Mike!";

Returns: Hello Mike!


You can also change the start of the greeting by reassigning a new string value to the
variable greeting .

greeting = "Hola";

greeting + " World!";

Returns: Hola World!


greeting + " Mike!";

Returns: Hola Mike!

JavaScript Has Three Ways to Declare Variables


- var , let , and const
In the example and video above, we used the keyword var to declare our variable.
When we use var we create a variable that is available in the global scope -- which
means it can be used anywhere in our program. We'll talk more about scope later, but
for now, keep in mind that globally scoped variables are not a good practice.

Here's why: in a small program with just a few variables, it's easy to keep track of the
variables and avoid collisions. But when you are working on a complex project or with a
large team. It is very easy to inadvertently overwrite an existing variable that is hidden in
another part of the program. let and const avoid this issue because they are only
available in the scope where they are declared. Again, more on scope later. For now,
remember:

JavaScript Has Three Ways to Declare Variables


- var , let , and const
In the example and video above, we used the keyword var to declare our
variable. When we use var we create a variable that is available in the global
scope -- which means it can be used anywhere in our program. We'll talk
more about scope later, but for now, keep in mind that globally scoped
variables are not a good practice.

Here's why: in a small program with just a few variables, it's easy to keep
track of the variables and avoid collisions. But when you are working on a
complex project or with a large team. It is very easy to inadvertently overwrite
an existing variable that is hidden in another part of the
program. let and const avoid this issue because they are only available in the
scope where they are declared. Again, more on scope later. For now,
remember:

Which to Use - let or const ?


 Use let when we think that the value of a variable might change
let lets us to assign a new value to the variable name when needed.
 Use const when we think that the value of a variable is fixed
A variable declared with const cannot be assigned a new value. It's value
is constant.

So which should be your default choice? That's easy. Pick the one that gives
you more control: const . Using const means that your program will throw an
error if there is an attempt to change the value of the variable when the code
runs. If that is an intended outcome, you can go back and revise your code to
declare the variable with let . If you did not intend for the value to change,
congratulations! You've just discovered a bug that you can fix before it causes
any problems.

Naming conventions
When you create a variable, you should write the name of the variable using
camelCase: the first word is lowercase, and all following words begin with a
capital letter. Additionally, aim to use a variable name that accurately yet
succinctly describes what the data represents.

// uses camelCase if the variable name is multiple words

const totalAfterTax = 53.03;

// uses lowercase if the variable name is one word

const tip = 8;

Not using camelCase for your variables names is not going to


necessarily break anything in JavaScript. But there are recommended style
guides used in all programming languages that help keep code consistent,
clean, and easy-to-read. This is especially important when working on larger
projects that will be accessed by multiple developers.

To convert Celsius(opens in a new tab) to Fahrenheit(opens in a new tab) , you can


use the following formula:
>F=C×1.8+32>>F=C×1.8+32>

Directions:
Use this equation and the variables fahrenheit and celsius to print the Fahrenheit
equivalent of 12°C.

NOTE: "12°C" reads as "12 degrees Celsius".

Running Your Code


Enter the following in the terminal:

node convert.js

Start Workspace

Workspaces will shut down after 30 minutes of inactivity. Any running processes will
be stopped.
Start Workspace

Workspaces may take up to 5 minutes to start.


View Active Workspaces

Try the quiz on your own first. If you get stuck you can check the solution by clicking the
button below.
Show Solution

LessonDownloads
Indexing
Did you know that you can access individual characters in a string? To access an
individual character, you can use the character's location in the string, called its index.
Just put the index of the character inside square brackets (starting with [0] as the first
character) immediately after the string. For example:

"James"[0];

Returns: "J"
or more commonly, you will see it like this, using a variable:

const name = "James";

name[0];

Returns: "J"
Show TranscriptSummarize Video

Note - This video does not have an audio. It was created as a visual to aid
learning.

Characters within a string are indexed starting from 0, where the first character is at
position 0, to n-1, where the last character is at position n-1 (n represents the total
number of characters within a string).

Quiz Question
What character will be printed to the JavaScript console after running the
following lines of code.

const quote = "Stay awhile and listen!";


console.log(quote[6]);

a
w

h
Submit

Escaping strings
There are some cases where you might want to create a string that contains
more than just numbers and letters. For example, what if you want to use
quotes in a string?

"The man whispered, "please speak to me.""

Uncaught SyntaxError: Unexpected identifier


If you try to use quotes within a string, you will receive a SyntaxError like the
one above.

Because you need to use quotes to denote the beginning and end of strings,
the JavaScript engine misinterprets the meaning of your string by
thinking "The man whispered, " is the string. Then, it sees the remaining please
speak to me."" and returns a SyntaxError .
If you want to use quotes inside a string, and have JavaScript not
misunderstand your intentions, you’ll need a different way to write quotes.
Thankfully, JavaScript has a way to do this using the backslash character
( \ ).
If you forget to use the backslash to escape characters, then the JavaScript engine can
misinterpret your strings.

Escaping characters
In JavaScript, you use the backslash to escape other characters.

Escaping a character tells JavaScript to ignore the character's special meaning and just
use the literal value of the character. This is helpful for characters that have special
meanings like in our previous example with quotes "…" .

Because quotes are used to signify the beginning and end of a string, you can use the
backslash character to escape the quotes in order to access the literal quote character.

"The man whispered, \"please speak to me.\""

Returns: The man whispered, "please speak to me."


This guarantees that the JavaScript engine doesn’t misinterpret the string and result in
an error.
Note - This video does not have an audio. It was created as a visual to aid
learning.

💡 By using the backslash to escape characters, the JavaScript engine can understand
the meaning of your strings.

Special characters
Quotes aren’t the only special characters that need to be escaped, there’s
actually quite a few(opens in a new tab) . However, to keep it simple, here’s a
list of some common special characters in JavaScript.
Code Character

\\ \ (backslash)

" '' (double quote)

' ' (single quote)

\n newline

\t tab

The last two characters listed in the table, newline \n and tab \t , are unique
because they add additional whitespace to your Strings. A newline character
will add a line break and a tab character will advance your line to the next tab
stop(opens in a new tab) .

"Up up\n\tdown down"

Returns:
Up up
down down

Comparing strings
Another way to work with strings is by comparing them. You've seen the comparison
operators == and != when you compared numbers for equality. You can also use
them with strings! For example, let’s compare the string "Yes" to "yes" .

"Yes" == "yes"
Returns: false
When you run this in the console, it returns false. Why is that? "Yes" and "yes" are
the same string, right? Well not quite.

A. Case-sensitive
When you compare strings, case matters. While both string use the same letters (and
those letters appear in the same order), the first letter in the first string is a
capital Y while the first letter in the second string is a lowercase y .

'Y' != 'y'

Returns: true

B. Internal Working
In Javascript, strings are compared character-by-character in alphabetical order. Each
character has a specific numeric value, coming from ASCII value of Printable
characters(opens in a new tab) . For example, the character 'A' has a value 65, and 'a'
has a value 97. You can notice that a lowercase letter has a higher ASCII value than the
uppercase character. If you want to know the ASCII value of a particular character, you
can try running the code below:

// Pick a string. Your string can have any number of


characters.

const my_string = "a";

// Calculate the ASCII value of the first character, i.e.


the character at the position 0.

const ASCII_value = my_string.charCodeAt(0);

// Let us print
console.log(ASCII_value);

In the example above, if you wish to print ASCII values of all the characters in your
string, you would have to use Loops that we will study in later part of this course. Just
for reference, here is how you can use a loop to print the ASCII value of all characters in
a string.

const my_string = "Udacity";

// Iterate using a Loop

for (let i = 0; i < my_string.length; i++) {

console.log(my_string.charCodeAt(i));

The ASCII values of [A-Z] fall in the range [65-90], whereas, the ASCII values of [a-z]
fall in the range [97-122]. Therefore, when we compare strings, the comparison
happens character-by-character for the ASCII values.

Directions:
Create a string with the name of your favorite food. The first letter of the string
should be capitalized.

Running Your Code


Enter the following in the terminal:

node favorite-food.js

Directions:
Fix the right side expression so it evaluates to true .
"ALL Strings are CrEaTeD equal" == "All STRINGS are
CrEaTED Equal"

Running Your Code


Enter the following in the terminal:

node equality.js

Directions:
Build a single string that resembles the following joke.

Why couldn't the shoes go out and play?

They were all "tied" up!

Your joke should take the format of a question and answer. The first line
should be a question and the second line should be an answer.

Hint: You will need to use special characters to produce the following output.

Running Your Code


Enter the following in the terminal:

node tied-up.js

Directions:
Build a string using concatenation by combining the lines from this famous
haiku poem by Yosa Buson(opens in a new tab) .

Blowing from the west

Fallen leaves gather


In the east.

Each string should be printed on its own line.

Hint: You will need to use special characters to produce the following output. For a
refresher, feel free to review the previous Escaping Strings topic in this lesson.

Running Your Code


Enter the following in the terminal:

node yosa-buson.js
A boolean variable can take either of two values - true or false . For example,

const studentName = "John";

const haveEnrolledInCourse = true;

const haveCompletedTheCourse = false;

A boolean variable is mainly essential in evaluating the outcome of conditionals


(comparisons). The result of a comparison is always a boolean variable. We'll study
conditionals in our upcoming lesson, but let's look at our previous example to
understand the role of boolean in conditional:

if (haveEnrolledInCourse) {

console.log("Welcome "+studentName+" to Udacity!");


// Will run only if haveEnrolledInCourse is true

Let's look at an example that will explain the role of a boolean variable in comparison.

const a = 10;

const b = 20;

// a comparison - we will study this in detail in


upcoming lesson

if (a>b) { // The outcome of a>b will be a boolean


console.log("Variable `a` has higher value"); // if
a>b is true

} else {

console.log("Variable `b` is greater than or equal to


`a`"); // if a>b is false

In general cases (regular equality check), a true corresponds to number 1,


whereas false represents a number 0. For example:

if (1) {
console.log("This statement will always execute
because conditional is set to 1 i.e., true");
}

if (0) {
console.log("This statement will NEVER execute
because conditional is set to 0 i.e., false");
}

Null, Undefined, and NaN


Show TranscriptSummarize Video

What is the Difference Between null and undefined ?

null refers to the "value of nothing", while undefined refers to the "absence of
value".

What is NaN?
NaN stands for "Not-A-Number" and it's often returned indicating an error with number
operations. For instance, if you wrote some code that performed a math calculation, and
the calculation failed to produce a valid number, NaN might be returned.
// calculating the square root of a negative number will
return NaN
Math.sqrt(-10)

// trying to divide a string by 5 will return NaN


"hello"/5

Equality
So far, you’ve seen how you can use == and != to compare numbers and strings for
equality. However, if you use == and != in situations where the values that you're
comparing have different data-types, it can lead to some interesting results. For
example,

"1" == 1

Returns: true
and

0 == false

Returns: true. The == operator is unable to differentiate 0 from false.


' ' == false

Returns: true. Both the operands on either side of the == operator are first converted
to zero, before comparison.
All of the above three evaluate to true. The reason for such interesting outcomes
is Type Conversion. In the case of regular comparison, the operands on either side of
the == operator are first converted to numbers, before comparison. Therefore, a '
' , false , and 0 are all considered equal. Similarly, a '1' and 1 are also considered
equal. If we don't want to convert the operands, before comparison, we have to use
a strict comparison === , that is explained below.

Implicit Type Coercion


JavaScript is known as a loosely typed language.
Basically, this means that when you’re writing JavaScript code, you do not need to
specify data types. Instead, when your code is interpreted by the JavaScript engine it
will automatically be converted into the "appropriate" data type. This is called implicit
type coercion and you’ve already seen examples like this before when you tried to
concatenate strings with numbers.

"julia" + 1

Returns: "julia1"
In this example, JavaScript takes the string "julia" and adds the number 1 to it
resulting in the string "julia1" . In other programming languages, this code probably
would have returned an error, but in JavaScript the number 1 is converted into the
string "1" and then is concatenated to the string "julia" .

It’s behavior like this which makes JavaScript unique from other programming
languages, but it can lead to some quirky behavior when doing operations and
comparisons on mixed data types.

Strongly Typed vs Loosely Typed


A strongly typed language is a programming language that is more likely to generate
errors if data does not closely match an expected type.

Example of strongly typed programming language code

int count = 1;

string name = "Julia";

double num = 1.2932;

float price = 2.99;

With a loosely typed language like JavaScript, you don’t need to specify data types;
this provides a lot more flexibility and is often faster to write. However, loose typing can
lead to errors that are hard to diagnose due to implicit type coercion.

Equivalent code in JavaScript


// equivalent code in JavaScript
let count = 1;
const name = "Julia";
const num = 1.2932;
const price = 2.99;

Strict vs. Loose Equality


In the example below, JavaScript takes the string "1" , converts it to true , and
compares it to the boolean true .

"1" == true

Returns: true
When you use the == or != operators, JavaScript first converts each value to the
same type (if they’re not already the same type); this is why it's called "type coercion"!
This is often not the behavior you want, and it’s actually considered bad practice to
use the == and != operators when comparing values for equality.

Instead, in JavaScript it’s better to use strict equality to see if numbers, strings, or
booleans, etc. are identical in type and value without doing the type conversion first. To
perform a strict comparison, simply add an additional equals sign = to the end of
the == and != operators.

"1" === 1

Returns: false
This returns false because the string "1" is not the same type and value as the
number 1 .

0 === false

Returns: false
This returns false because the number 0 is not the same type and value as the
boolean false . Just like strict equality operator, there is also a strict non-
equality operator !== that can be used instead of != if you don't want a type-
conversion, before comparison. For example,

0 !== true

Returns: true
and

'1' !== 1

Returns: true
One thing to take notice of in all the examples you've seen so far is the use of
semicolons ; at the end of each line. Semicolons make it clear where one statement
ends and another begins. This is especially handy when multiple lines of code are
written on the same line (which is valid JavaScript, but definitely not recommended!).
For instance:

const totalAfterTax = 53.03 let tip = 8 // this is


incorrect!

Uncaught SyntaxError: Unexpected token var


vs.

const totalAfterTax = 53.03; let tip = 8; // this is


correct!

Not adding semicolons to the end of each line can cause bugs and errors in your
programs. JavaScript does have ways to occasionally predict where
semicolons should be, but just like how type coercion can result in some unexpected
quirky behavior in JavaScript, it's good practice to not depend on it.

Directions for the Quiz Below:


Define two variables called thingOne and thingTwo and assign them values. Print the
values of both variables in one console.log statement using concatenation. For
example,

red blue
where "red" is the value of thingOne and "blue" is the value of thingTwo . Don't
forget to use semicolon at the end of each statement!

Running Your Code


Enter the following in the terminal:

node semicolons.js

Start Workspace

Workspaces will shut down after 30 minutes of inactivity. Any running processes will
be stopped.
Start Workspace

Workspaces may take up to 5 minutes to start.


View Active Workspaces

Try the quiz on your own first. If you get stuck you can check the solution by clicking the
button below.
Show Solution

Directions:
Create a variable called fullName and assign it your full name as a string.
Print the value of the variable in the console.

Try the quiz on your own first. If you get stuck you can check the solution by clicking the
button below.
Show Solution
Directions:
Create a variable called bill and assign it the result of 10.25 + 3.99 +
7.15 (don't perform the calculation yourself, let JavaScript do it!). Next, create
a variable called tip and assign it the result of multiplying bill by a 15% tip
rate. Finally, add the bill and tip together and store it into a variable
called total .

Print the total to the JavaScript console.

Hint: 15% in decimal form is written as 0.15 .

TIP: To print out the total with a dollar sign ( $ ) use string concatenation. To
round total up by two decimal points use the toFixed() method. To
use toFixed() pass it the number of decimal points you want to use. For example,
if total equals 3.9860 , then total.toFixed(2) would return 3.99 .

Running Your Code


Enter the following in the terminal:

node dinner.js

Directions:
Mad Libs(opens in a new tab) is a word game where players have fun
substituting words for blanks in a story. For this exercise, use the adjective
variables below to fill in the blanks and complete the following message.

"The Intro to JavaScript course is __________. James and


Julia are

so __________. I cannot wait to work through the rest of

this __________ content!"


const adjective1 = "amazing";

const adjective2 = "fun";

const adjective3 = "entertaining";

Assign the resulting string to a variable called madLib .

Running Your Code


Enter the following in the terminal:

node mad-libs.js

Directions:
Here are two awesome messages:

Hi, my name is Julia. I love cats. In my spare time, I


like to play video games.

Hi, my name is James. I love baseball. In my spare time,


I like to read.

Declare and assign values to three variables for each part of the sentence that
changes ( firstName , interest , and hobby ).

Use your variables and string concatenation to create your own awesome
message and store it in an awesomeMessage variable. Finally, print your
awesome message to the JavaScript console.

Running Your Code


Enter the following in the terminal:
Great Work!
In this lesson, we covered all the basic data types in JavaScript, including
numbers, strings,boolean, null and undefined.

We also learned how you can store data in variable and we practiced some
operations on numbers and strings.

In the next lesson, we'll build upon your new knowledge of data types and
variables to learn how to write code to solve logical problems.
DEFINITION: A flowchart is a visual diagram that outlines the solution to a problem through a
series of logical statements. The order in which statements are evaluated and executed is called
the control flow.

Flowcharts are a great way to visualize a problem before you start writing code.

Question 1 of 2
Take a look at the flowchart above. What data type would best represent (Yes/No) if you
have enough money to purchase the item?

Number

Solving the Problem: Do I purchase the hammer?


To answer that question we need to know:

 How much money do I have?


 How much does the hammer cost?

Let's translate that into code:

const price = 15.00;

const money = 20.00;

Now we compare the price to the money we have to determine if we have enough
money. We can use a JavaScript if else statement for that:

if (money >= price) {

console.log("buy the hammer");

} else {

console.log("don't buy the hammer");

Pay attention to the curly braces! The code in the curly braces after the if statement
will run if the statement evaluates to true and the code in the curly braces after
the else statement will run if it evaluates to false .

Why does the video use var and the example code
use const ?
Although var works, it is now considered best practice to use let or const instead.
We're showing you both but you should try to use let and const in your own code.

If...else Statements
If...else statements allow you to execute certain pieces of code based on a condition, or set of
conditions, being met.

if (/ *this expression is true* /) {

// run this code

} else {

// run this code

This is extremely helpful because it allows you to choose which piece of code you want to run
based on the result of an expression. For example,

const a = 1;

const b = 2;

if (a > b) {

console.log("a is greater than b");

} else {

console.log("a is less than or equal to b");

Prints: "a is less than or equal to b"


A couple of important things to notice about if...else statements.

The value inside the if statement is always converted to true or false. Depending on the value,
the code inside the if statement is run or the code inside the else statement is run, but not both.
The code inside the if and else statements are surrounded by curly braces {...} to separate
the conditions and indicate which code should be run.

TIP: When coding, sometimes you may only want to use an if statement. However, if you try to
use only an else statement, then you will receive the error SyntaxError: Unexpected token
else . You’ll see this error because else statements need an if statement in order to work. You
can’t have an else statement without first having an if statement.

Test Your if else Intuition


Are curly braces always necessary?

Question 1 of 2
We've removed the curly braces after the if and else statements. What do you think will
happen if you run this code:

const a = 1;
const b = 2;

if (a > b)
console.log('a is greater than b');
else
console.log('a is less than or equal to b');

You'll get an error message: Uncaught SyntaxError: Unexpected token 'else'


We've removed the curly braces after the if and else statements. What do you
think will happen if you run this code:

const a = 1;
const b = 2;

if (a > b)
console.log('a is greater than b');
a = a + 2;
else
console.log('a is less than or equal to b');
You'll get an error message: Uncaught SyntaxError: Unexpected token 'else'

The code will run as expected and return a is less than or equal to b

The code will run return an incorrect response: a is greater than b


Submit

What We Learned
Curly braces are not necessary if you have only one line of code to execute following
an if or else statement. They are necessary if you have more than one line of code to
execute.

That being. said, in most cases, even though it is not required, it is a better practice to
use curly braces whenever you are using a conditional statement.

Learn More
Read the documentation: MDN Web Docs - if else(opens in a new tab)
More Conditionals!
In some situations, two conditionals aren’t enough. Consider the following situation.

You're trying to decide what to wear tomorrow. If it is going to snow, then you’ll want to
wear a coat. If it's not going to snow and it's going to rain, then you’ll want to wear a
jacket. And if it's not going to snow or rain, then you’ll just wear what you have on.
Flowchart for deciding what to wear tomorrow.

Else if statements
In JavaScript, you can represent this secondary check by using an extra if statement
called an else if statement.

const weather = "sunny";

if (weather === "snow") {

console.log("Bring a coat.");

} else if (weather === "rain") {

console.log("Bring a rain jacket.");

} else {

console.log("Wear what you have on.");

Prints: Wear what you have on.


By adding the extra else if statement, you're adding an extra conditional statement.

If it’s not going to snow, then the code will jump to the else if statement to see if it’s
going to rain. If it’s not going to rain, then the code will jump to the else statement.

The else statement essentially acts as the "default" condition in case all the
other if statements are false.

Question 1 of 2
What will be printed to the console if the following code is run?

const money = 100.50;


const price = 100.50;

if (money > price) {


console.log("You paid extra, here's your change.");
} else if (money === price) {
console.log("You paid the exact amount, have a nice day!");
} else {
console.log("That's not enough, you still owe me money.");
}

"You paid extra, here's your change."

"You paid the exact amount, have a nice day!"

"That's not enough, you still owe me money."

None of the above


Submit

Question 2 of 2
Looking at the following code, determine what medal Kendyll received.

const runner = "Kendyll";


const position = 2;
let medal;
if(position === 1) {
medal = "gold";
} else if(position === 2) {
medal = "silver";
} else if(position === 3) {
medal = "bronze";
} else {
medal = "pat on the back";
}

console.log(runner + " received a " + medal + " medal.");

Quiz: Even or Odd


LessonDownloads

Directions:
Write an if...else statement that:

 prints "even" if the number is an even number


 prints "odd" if the number is an odd number

Hint: Use the % (modulo(opens in a new tab) ) operator to determine if a number is


even or odd. The modulo operator takes two numbers and returns the remainder when
the first number is divided by the second one:
console.log(12 % 3);
console.log(10 % 4);
Result:
0
2
The answer for 12 % 3 is 0 because twelve divided by three has no remainder. 10
% 4 is 2 because ten divided by 4 has a remainder of two.
Make sure to test your code with different values. For example:

 If number equals 1 , then odd should be printed to the console.


 If number equals 12 , then even should be printed to the console.

Running Your Code


Enter the following in the terminal:

node even-or-odd.js
Node.js(opens in a new tab) is an open-source backend JavaScript runtime
environment. That basically means that it will run your JavaScript code in the terminal
and return any output that is generated. We'll be using Node to run the code in our
workspaces for many of the quizzes in this course.

Testing Your Code


How will you know if your code works? Change the value of number and re-run the
code.

Value of number Expected Output

3 odd

14 even

5984 even

35425413 odd

⚠️These workspaces will autosave your code -- but it can take a few seconds.
If you try to run your code before the autosave occurs, you will see an error like this:
ReferenceError: Cannot access 'variableName' before initialization
Wait a few seconds and try to run the code again.
Musical groups have special names based on the number of people in the group.

For example, a "quartet" is a musical group with four musicians. Barbershop


quartets(opens in a new tab) were a popular type of quartet in the early 1900s and
featured four singers made up of a lead, tenor, baritone, and bass.

Directions:
Write a series of conditional statements that:

 Prints "not a group" if musicians is less than or equal to 0


 Prints "solo" if musicians is equal to 1
 Prints "duet" if musicians is equal to 2
 Prints "trio" if musicians is equal to 3
 Prints "quartet" if musicians is equal to 4
 Prints "this is a large group" if musicians is greater than 4

HINT If you aren't sure how to proceed, try drawing a flow chart to outline the decision
points and how the decision is made at each point

Running Your Code


Enter the following in the terminal:

node musical-groups.js

Testing Your Code


How will you know if your code works? Change the value of number and re-run the
code.
Value of musicians Output

0 "not a group"

1 "solo"

2 "duet"

3 "trio"

4 "quartet"

76 "this is a large group"

Problems Aren't Always Simple


With most problems there's more things to consider before you can actually
solve the problem.

Example: Deciding what to do this weekend

Julia's plan is to hang out with her friend Colt at the park.

For Julia's plans to work:

1. Colt must be available


2. The weather must be nice
In JavaScript we can represent complex problems by combining logical
expressions with special operators called logical operators.
Here’s the logical expression used to represent Julia’s weekend plans:

var colt = "not busy";

var weather = "nice";

if (colt === "not busy" && weather === "nice") {

console.log("go to the park");

Prints: "go to the park"


Notice the && in the code above.

The && symbol is the logical AND operator, and it is used to combine two
logical expressions into one larger logical expression. If both smaller
expressions are true, then the entire expression evaluates to true. If either
one of the smaller expressions is false, then the whole logical expression
is false.

Another way to think about it is when the && operator is placed between the
two statements, the code literally reads, "if Colt is not busy AND the weather is
nice, then go to the park".

Logical expressions
Logical expressions are similar to mathematical expressions, except logical
expressions evaluate to either true or false.

11 != 12

Returns: true
You’ve already seen logical expressions when you write comparisons. A
comparison is just a simple logical expression.
Similar to mathematical expressions that use + , - , * , / and % , there are
logical operators && , || and ! that you can use to create more complex
logical expressions.

Logical operators
Logical operators can be used in conjunction with boolean values
( true and false ) to create complex logical expressions.

By combining two boolean values together with a logical operator, you create
a logical expression that returns another boolean value. Here’s a table
describing the different logical operators:

Operato Meanin
Example How it works
r g

value1
Logical Returns true if both value1 and value2 ev
&& &&
AND aluate to true .
value2

value1
Logical Returns true if either value1 or value2 (or
|| ||
OR even both!) evaluates to true .
value2

Logical ! Returns the opposite of value1 .


!
NOT value1 If value1 is true , then !value1 is false .

By using logical operators, you can create more complex conditionals like
Julia’s weekend example.
Here’s the logical expression used to represent Julia’s weekend plans:
var colt = "not busy";

var weather = "nice";

if (colt === "not busy" && weather === "nice") {

console.log("go to the park");

Prints: "go to the park"


Notice the && in the code above.

The && symbol is the logical AND operator, and it is used to combine two
logical expressions into one larger logical expression. If both smaller
expressions are true, then the entire expression evaluates to true. If either
one of the smaller expressions is false, then the whole logical expression
is false.

Another way to think about it is when the && operator is placed between the
two statements, the code literally reads, "if Colt is not busy AND the weather is
nice, then go to the park".

Logical expressions
Logical expressions are similar to mathematical expressions, except logical
expressions evaluate to either true or false.

11 != 12

Returns: true
You’ve already seen logical expressions when you write comparisons. A
comparison is just a simple logical expression.

Similar to mathematical expressions that use + , - , * , / and % , there are


logical operators && , || and ! that you can use to create more complex
logical expressions.
Logical operators
Logical operators can be used in conjunction with boolean values
( true and false ) to create complex logical expressions.

By combining two boolean values together with a logical operator, you create
a logical expression that returns another boolean value. Here’s a table
describing the different logical operators:

Operato Meanin
Example How it works
r g

value1
Logical Returns true if both value1 and value2 ev
&& &&
AND aluate to true .
value2

value1
Logical Returns true if either value1 or value2 (or
|| ||
OR even both!) evaluates to true .
value2

Logical ! Returns the opposite of value1 .


!
NOT value1 If value1 is true , then !value1 is false .

By using logical operators, you can create more complex conditionals like
Julia’s weekend example.
Before you advance any further in the lesson, here’s the truth tables for logical AND
( && ) and logical OR ( || ).
Truth Tables

&& (AND)
A B A && B

true true true

true false false

false true false

false false false

|| (OR)
A B A || B

true true true

true false true

false true true


A B A || B

false false false

Truth tables are used to represent the result of all the possible combinations of inputs
in a logical expression. A represents the boolean value on the left-side of the
expression and B represents the boolean value on the right-side of the expression.

Truth tables can be helpful for visualizing the different outcomes from a logical
expression. However, do you notice anything peculiar about the truth tables for logical
AND and OR?
Short-circuiting

In some scenarios, the value of B in logical AND and OR doesn't matter.


In both tables, there are specific scenarios where regardless of the value of B , the
value of A is enough to satisfy the condition.

For example, if you look at A AND B , if A is false, then regardless of the value B , the
total expression will always evaluate to false because both A and B must be true in
order for the entire expression to be true .

This behavior is called short-circuiting because it describes the event when later
arguments in a logical expression are not considered because the first argument
already satisfies the condition.
Quiz: Murder Mystery
LessonDownloads

Directions:
For this quiz, you're going to help solve a fictitious murder mystery(opens in a new
tab) that happened here at Udacity! A murder mystery is a game typically played at
parties wherein one of the partygoers is secretly, and unknowingly, playing a murderer,
and the other attendees must determine who among them is the criminal. It's a classic
case of whodunnit(opens in a new tab) .

Since this might be your first time playing a murder mystery, we've simplified things
quite a bit to make it easier. Here's what we know! In this murder mystery there are:

 four rooms: the ballroom, gallery, billiards room, and dining room,
 four weapons: poison, a trophy, a pool stick, and a knife,
 and four suspects: Mr. Parkes, Ms. Van Cleve, Mrs. Sparr, and Mr. Kalehoff.

We also know that each weapon corresponds to a particular room, so...

 the poison belongs to the ballroom ,


 the trophy belongs to the gallery ,
 the pool stick belongs to the billiards room ,
 and the knife belongs to the dining room .

And we know that each suspect was located in a specific room at the time of the
murder.

 Mr. Parkes was located in the dining room .


 Ms. Van Cleve was located in the gallery .

 Mrs. Sparr was located in the billiards room .

 Mr. Kalehoff was located in the ballroom .


To help solve this mystery, write a combination of conditional statements that:

1. sets the value of weapon based on the room and


2. sets the value of solved to true if the value of room matches the suspect 's
room

Afterwards, use this template to print a message to the console if the mystery was
solved:

__________ did it in the __________ with the __________!

What goes into the three blank spaces? You can fill in the blanks with the name of the
suspect, the room, and the weapon! For example, an output string may look like:

Mr. Parkes did it in the dining room with the knife!

Running Your Code


Enter the following in the terminal:

node murder-mystery.js

Testing Your Code


How will you know if your code works? Change the values of room and suspect and
re-run the code. If the case is solved, you should get the solution printed in the console,
e.g. "Ms. Van Cleve did it in the gallery with the trophy!" .

If the case is not solved, you should get a message saying "The case is not solved!"

Expected Outcomes

room suspect Case is Solved?

dining room Mr. Parkes Yes


room suspect Case is Solved?

gallery Ms. Van Cleve Yes

billiards room Mrs. Sparr Yes

ballroom Mr. Kalehoff Yes

billiards room Ms. Van Cleve No

dining room Mrs. Sparr No

gallery Mr. Kalehoff No

ballroom Mr. Parkes No

Quiz: Checking your Balance


LessonDownloads

Directions:
Using the flowchart below, write the code to represent checking your balance at the
ATM. The yellow diamonds represent conditional statements and the blue rectangles
with rounded corners represent what should be printed to the console.
Flowchart for checking your balance at the ATM (Click the image to enlarge the
flowchart).
Use the following variables in your solution:
 balance - the account balance
 isActive - if account is active

 checkBalance - if you want to check balance

Hint: The variable balance could be a value less than, greater than, or equal to 0. The
variables isActive and checkBalance are booleans that can be set to true or false.

TIP: To print out the account balance with decimal points (i.e. 325.00), use
the .toFixed() method and pass it the number of decimal points you want to use. For
example, balance.toFixed(2) returns 325.00.

Running Your Code


Enter the following in the terminal:

node balance.js

Testing Your Code


How will you know if your code works? Change the values
of balance , checkBalance and isActive and re-run the code and compare your
output with the expected output.

Expected Output

Custome bala checkBal isAct


Expected Output
r nce ance ive

Your balance is negative.


Customer1 -325 true true
Please contact bank.
Custome bala checkBal isAct
Expected Output
r nce ance ive

Customer2 35 true true Your balance is $35.00.

Customer3 35 false true Thank you. Have a nice day!

Your account is no longer


Customer4 35 true false
active.

Customer5 0 true true Your account is empty.

Customer6 -325 false true Thank you. Have a nice day!

Your account is no longer


Customer7 -325 true false
active.

Customer8 35 false false Thank you. Have a nice day!

Customer9 0 false false Thank you. Have a nice day!

Customer1 Your account is no longer


0 true false
0 active.
Quiz: Ice Cream
LessonDownloads

Directions:
Ice cream is one of the most versatile desserts on the planet because it can be done up
so many different ways and every ice cream shop offers a different set of flavors,
toppings and serving vessels.

Using logical operators, write a series of complex logical expressions that evaluates a
cusomer order and prints an approriate response.

If the order can be filled, respond with:

"Great choice! Your ice cream is at the next window."

If the order cannot be filled, respond with:

"Please check our menu and try again."

Our Ice Cream Store offers the following:

 Flavors: vanilla or chocolate


 Topping: sprinkles or peanuts
 Vessel: wafer cone or sugar cone

Running Your Code


Enter the following in the terminal:

node ice-cream.js

Testing Your Code


How will you know if your code works? Change the values
of flavor , topping and vessel and re-run the code and compare your output with the
expected output.

Expected Output

Flavor Topping Vessel Response

chocola banan wafer "Please check our menu and try


te as cone again."

chocola peanu wafer "Great choice! Your ice cream is at


te ts cone the next window."

chocola sprink sugar "Great choice! Your ice cream is at


te les cone the next window."

chocola sprink "Please check our menu and try


bowl
te les again."

strawb sprink wafer "Please check our menu and try


erry les cone again."

strawb banan sugar "Please check our menu and try


erry as cone again."
Flavor Topping Vessel Response

strawb peanu "Please check our menu and try


bowl
erry ts again."

sprink wafer "Great choice! Your ice cream is at


vanilla
les cone the next window."

peanu sugar "Great choice! Your ice cream is at


vanilla
ts cone the next window."

sprink "Please check our menu and try


vanilla bowl
les again."

If you're like me, finding the right size t-shirt can sometimes be a challenge. What size
am I? What's the difference between S (small), M (medium), and L (large)? I usually
wear L, but what if I need an XL (extra large)?

Thankfully, our friends at Teespring(opens in a new tab) have got us covered


because they've created a sizing chart to make things a lot easier.

T-Shirt Sizing Chart


Size Width Length Sleeve

S 18" 28" 8.13"


Size Width Length Sleeve

M 20" 29" 8.38"

L 22" 30" 8.63"

XL 24" 31" 8.88"

2XL 26" 33" 9.63"

3XL 28" 34" 10.13"

Source: Teespring.com

Directions:
Use the sizing chart above, create a series of logical expressions that prints the size of
a t-shirt based on the measurements of shirtWidth , shirtLength , and shirtSleeve . Valid
sizes include S , M , L , XL , 2XL , and 3XL .

For example, if...

const shirtWidth = 23; // size L (large)

const shirtLength = 30; // size L (large)

const shirtSleeve = 8.71; // size L (large)

Then print L to the console.

Hint: You will need to compare a range of values when checking


for shirtWidth , shirtLength , and shirtSleeve . For example, if the shirt's width is at
least 20", but no more than 22", then the t-shirt should be medium (M) — as long as
the other values for the shirt's length and sleeve measurements match up.

If shirtWidth , shirtLength , and shirtSleeve don't fit within the range of acceptable
values for a specific size, then print NA to the console. For example, if...

const shirtWidth = 18; // size S (small)

const shirtLength = 29; // size M (medium)

const shirtSleeve = 8.47; // size M (medium)

Then print N/A to the console because the measurements don't all match up with one
particular size .

Running Your Code


Enter the following in the terminal:

node what-wear.js

Testing Your Code


How will you know if your code works? Change the values
of shirtWidth , shirtLength and shirtSleeve and re-run the code and compare your
output with the expected output.

Expected Output

Width Length Sleeve Size

18 28 8.13 S
Width Length Sleeve Size

19.99 28.99 8.379 S

20 29 8.38 M

22 30 8.63 L

24 31 8.88 XL

26 33 9.63 2XL

27.99 33.99 10.129 2XL

28 34 10.13 3XL

18 29 8.47 NA

Beyond The Basics


We've covered the the basics of conditionals and logical operators -- but there
is more to learn!

In the rest of this lesson, we'll focus on some more advanced aspects of
working with conditional statements:

 Truthy and falsy values


 The ternary operator
 The switch statement

Truthy and Falsy


LessonDownloads

Truthy and Falsy


Every value in JavaScript has an inherent boolean value. When that value is evaluated
in the context of a boolean expression, the value will be transformed into that inherent
boolean value.

The paragraph above is pretty dense with information. You should probably re-read it
again! ☝️

Falsy values
A value is falsy if it converts to false when evaluated in a boolean context. For
example, an empty String "" is falsy because, "" evaluates to false . You already
know if...else statements, so let's use them to test the truthy-ness of "" .

if ("") {

console.log("the value is truthy");

} else {

console.log("the value is falsy");

Returns: "the value is falsy"

Here’s the list of all of the falsy values:


1. the Boolean value false
 the null type
 the undefined type
 the number 0
 the empty string ""
 the odd value NaN (stands for "not a number", check out the NaN MDN
article(opens in a new tab))

That's right, there are only six falsy values in all of JavaScript!

Truthy values
A value is truthy if it converts to true when evaluated in a boolean context. For
example, the number 1 is truthy because, 1 evaluates to true . Let's use an if...else
statement again to test this out:

if (1) {

console.log("the value is truthy");

} else {

console.log("the value is falsy");

Returns: "the value is truthy"


Here are some other examples of truthy values:

true

42

"pizza"

"0"

"null"
"undefined"

{}

[]

Essentially, if it's not in the list of falsy values, then it's truthy!

Truthy and Falsy


LessonDownloads

Truthy and Falsy


Every value in JavaScript has an inherent boolean value. When that value is evaluated
in the context of a boolean expression, the value will be transformed into that inherent
boolean value.

The paragraph above is pretty dense with information. You should probably re-read it
again! ☝️

Falsy values
A value is falsy if it converts to false when evaluated in a boolean context. For
example, an empty String "" is falsy because, "" evaluates to false . You already
know if...else statements, so let's use them to test the truthy-ness of "" .

if ("") {

console.log("the value is truthy");

} else {

console.log("the value is falsy");

Returns: "the value is falsy"


Here’s the list of all of the falsy values:
1. the Boolean value false

 the null type


 the undefined type
 the number 0
 the empty string ""
 the odd value NaN (stands for "not a number", check out the NaN MDN
article(opens in a new tab))

That's right, there are only six falsy values in all of JavaScript!

Truthy values
A value is truthy if it converts to true when evaluated in a boolean context. For
example, the number 1 is truthy because, 1 evaluates to true . Let's use an if...else
statement again to test this out:

if (1) {

console.log("the value is truthy");

} else {

console.log("the value is falsy");

Returns: "the value is truthy"


Here are some other examples of truthy values:

true

42

"pizza"
"0"

"null"

"undefined"

{}

[]

Essentially, if it's not in the list of falsy values, then it's truthy!
Open the developer console in your browser to test the output of options
mention in the above quiz.

if(< Write your condition here >)


console.log("This text will be printed if the
condition above evaluates

Ternary Operator
LessonDownloads

Sometimes, you might find yourself with the following type of conditional.

const isGoing = true;

const color;

if (isGoing) {

color = "green";

} else {

color = "red";

console.log(color);
Prints: "green"
In this example, the variable color is being assigned to either "green" or "red" based
on the value of isGoing . This code works, but it’s a rather lengthy way for assigning a
value to a variable. Thankfully, in JavaScript there’s another way.

TIP: Using if(isGoing) is the same as using if(isGoing === true) . Alternatively,
using if(!isGoing) is the same as using if(isGoing === false) .

Ternary operator
The ternary operator provides you with a shortcut alternative for writing lengthy if...else
statements.

conditional ? (if condition is true) : (if condition is


false)

To use the ternary operator, first provide a conditional statement on the left-side of
the ? . Then, between the ? and : write the code that would run if the condition
is true and on the right-hand side of the : write the code that would run if the condition
is false . For example, you can rewrite the example code above as:

const isGoing = true;

const color = isGoing ? "green" : "red";

console.log(color);

Prints: "green"
This code not only replaces the conditional, but it also handles the variable assignment
for color .

If you breakdown the code, the condition isGoing is placed on the left side of the ? .
Then, the first expression, after the ? , is what will be run if the condition is true and the
second expression after the, : , is what will be run if the condition is false.

Example
Here's a comparison of using an if...else statement vs. using a ternary operator.
Show TranscriptSummarize Video

Note - This video does not have an audio. It was created as a visual to aid
learning.

What is the result of the ternary expression? javascript const x = 4; const y = 3; (x + y)


>6?2x:2y;

*Enter only the numerical response -- no extra


characters*

Quiz: Navigating the Food Chain


LessonDownloads

From the smallest of creatures to the largest of animals, inevitably every living,
breathing thing must ingest other organisms to survive. This means that all animals will
fall within one of the three consumer-based categories based on the types of food that
they eat.

 Animals that eat only plants are called herbivores


 Animals that eat only other animals are called carnivores
 Animals that eat both plants and animals are called omnivores

Directions:
Write a series of nested ternary statements that sets the variable category equal to:

 "herbivore" if an animal eats plants


 "carnivore" if an animal eats animals

 "omnivore" if an animal eats plants and animals

 "undefined" if an animal doesn't eat plants or animals

HINT If you get stuck, try drawing a diagram of the decision tree.
Running Your Code
Create a file named food-chain.js , implement the solution, and run the command below
on your terminal:

node food-chain.js

Testing Your Code


How will you know if your code works? Change the values
of eatsPlants and eatsAnimals and re-run the code and compare your output with the
expected output.

Expected Output

Eats Plants Eats Animals Expected Output

true false "herbivore"

true true "omnivore"

false true "carnivore"

false false undefined

If you find yourself repeating else if statements in your code, where each condition is
based on the same value, like this:

if (option === 1) {

console.log("You selected option 1.");

} else if (option === 2) {


console.log("You selected option 2.");

} else if (option === 3) {

console.log("You selected option 3.");

} else if (option === 4) {

console.log("You selected option 4.");

} else if (option === 5) {

console.log("You selected option 5.");

} else if (option === 6) {

console.log("You selected option 6.");

then it might be time to use a switch statement.

Switch Statement
A switch statement is an another way to chain multiple else if statements that are
based on the same value without using conditional statements. Instead, you
just switch which piece of code is executed based on a value.

switch (option) {

case 1:

console.log("You selected option 1.");

case 2:

console.log("You selected option 2.");

case 3:

console.log("You selected option 3.");

case 4:
console.log("You selected option 4.");

case 5:

console.log("You selected option 5.");

case 6:

console.log("You selected option 6.");

Here, each else if statement ( option === [value] ) has been replaced with
a case clause ( case [value]: ) and those clauses have been wrapped inside the switch
statement.

Switch Looks for Matching Values


When the switch statement evaluates, it starts at the top and looks for a case clause
whose expression evaluates to the same value as the result of the expression passed to
the switch statement.

When it finds a match, it transfers control to that case clause to executed the code for
that case.

So, if you set option equal to 3 ...

const option = 3;

switch (option) {

...

Prints:
You selected option 3.
You selected option 4.
You selected option 5.
You selected option 6.
...then the switch statement prints out options 3, 4, 5, and 6.

But that’s not exactly like the original if...else code at the top? So what’s missing?

Use Break to Avoid Falling Through


After the code in the matching case is run, the switch statement continues to run all of
the code below that statement too! This is called falling through.

We can prevent the code from falling through by adding a break statement at the end
of each case.

The break statement will terminate the switch statement and transfer control to the
code following the switch statement which prevents the switch statement from falling
through and running the code in the other case clauses.

const option = 3;

switch (option) {

case 1:

console.log("You selected option 1.");

break;

case 2:

console.log("You selected option 2.");

break;

case 3:

console.log("You selected option 3.");

break;
case 4:

console.log("You selected option 4.");

break;

case 5:

console.log("You selected option 5.");

break;

case 6:

console.log("You selected option 6.");

break; // technically, not needed

Prints: You selected option 3.

Set a Default Case


What happens if none of the cases match? Nothing -- because there is no code to run.
That works in some situations, but it most cases you'll want to add a default case to
catch situations when none of the case statements match.

const option = 23;

switch (option) {

case 1:

console.log("You selected option 1.");

break;

case 2:

console.log("You selected option 2.");


break;

case 3:

console.log("You selected option 3.");

break;

case 4:

console.log("You selected option 4.");

break;

case 5:

console.log("You selected option 5.");

break;

case 6:

console.log("You selected option 6.");

break;

default:

console.log("You did not select a valid option.");

Prints: You did not select a valid option.


It is good practice to always set a default case.
Does it matter where the default statement is placed?
What is the output from this code:

const favoriteFood = "soup";


let restaurant = undefined;

switch(favoriteFood) {
case "pizza":
restaurant ="pizzeria";
break;
default:
restaurant ="diner";
break;
case "tacos":
restaurant ="taqueria";
break;
case "sushi":
restaurant ="sushi bar";
break;
case "pancakes":
restaurant ="pancake house";
break;
}

console.log("Go to the " + restaurant);


What is the output from the following switch statement?

const month = 7;
let days;

switch(month) {
case 1:
case 2:
days = 28;
break;
case 3:
case 4:
days = 30;
break;
case 5:
case 6:
days = 30;
break;
case 7:
case 8:
case 9:
days = 30;
break;
case 10:
case 11:
days = 30;
break;
case 12:
default:
days = 31;
}

console.log("There are " + days + " days in this


month.");
What is the output from the following switch statement?

const month = 5;
let days;

switch (month) {
case 1:
days = 31;
break;
case 2:
days = 28;
break;
case 3:
days = 31;
break;
case 4:
days = 30;
break;
case 5:
days = 31;
break;
case 6:
days = 30;
break;
case 7:
days = 31;
break;
case 8:
days = 31;
break;
case 9:
days = 30;
break;
case 10:
days = 31;
break;
case 11:
days = 30;
break;
case 12:
days = 31;
}

console.log('There are ' + days + ' days in this


month.');
What is the output from the following switch statement?

var month = 2;

switch(month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
days = 31;
break;
case 4:
case 6:
case 9:
case 11:
days = 30;
break;
case 2:
days = 28;
}
console.log("There are " + days + " days in this
month.");
In some situations, you might want to leverage the "falling-through" behavior of switch
statements to your advantage.

For example, when your code follows a hierarchical-type structure.

const tier = "nsfw deck";

let output = "You’ll receive "

switch (tier) {

case "deck of legends":

output += "a custom card, ";

case "collector's deck":

output += "a signed version of the Exploding Kittens


deck, ";

case "nsfw deck":

output += "one copy of the NSFW (Not Safe for Work)


Exploding Kittens card game and ";

default:

output += "one copy of the Exploding Kittens card


game.";

console.log(output);

Prints: You’ll receive one copy of the NSFW (Not Safe for Work) Exploding Kittens card
game and one copy of the Exploding Kittens card game.
In this example, based on the successful Exploding Kittens Kickstarter
campaign(opens in a new tab) (a hilarious card game created by Elan Lee), each
successive tier builds on the next by adding more to the output. Without any break
statements in the code, after the switch statement jumps to the "nsfw deck" , it
continues to fall-through until reaching the end of the switch statement.

Also, notice the default case.

const tier = "none";

let output = "You’ll receive ";

switch (tier) {

...

default:

output += "one copy of the Exploding Kittens card


game.";

console.log(output);

Prints: You’ll receive one copy of the Exploding Kittens card game.
By using the falling-through behavior of switch statements, you can represent
hierarchical-type scenarios like the Kickstarter backer program.
If winner is equal to 3, then what will be output to the console?

let prize = "";

switch (winner) {
case 1:
prize += "a trip for two to the Bahamas and ";
case 2:
prize += "a four piece furniture set.";
break;
case 3:
prize += "a smartwatch and ";
default:
prize += "tickets to the circus.";
}

console.log("You've won " + prize);


In 2015, the U.S. Bureau of Labor Statistics conducted research(opens in a new
tab) to reveal how average salary is directly related to the number of years spent in
school. In their findings, they found that people with:

 no high school diploma earned an average of $25,636/year,


 a high school diploma earned an average of $35,256/year,

 an Associate's degree earned an average of $41,496/year,

 a Bachelor's degree earned an average of $59,124/year,

 a Master's degree earned an average of $69,732/year,

 a Professional degree earned an average of $89,960/year,

 and a Doctoral degree earned an average of $84,396/year.

NOTE: Wondering what the average salary would be for a person with a Nanodegree
from Udacity? That's a hard question to answer, but that doesn't mean we haven't tried
to quantify the value of our Nanodegrees. Read more about Nanodegrees from
resident Udacity writer, Chris Watkins, here(opens in a new tab)

Directions:
Write a switch statement to set the average salary of a person based on their type of
completed education.

Afterwards, print the following to the console.

In 2015, a person with __________ earned an average of


__________/year.
Fill in the blanks with the type of education and the expected average salary. Make sure
to use correct grammar in your printed statement, and watch out for any extra or
missing characters (including spaces and punctuation marks). For help, refer to the
findings above.

In 2015, a person with a Bachelor's degree earned an


average of $59,124/year.

TIP: To print out the average salary with commas (i.e. 59,124), use
the toLocaleString() method and pass it the locale "en-US". For
example, salary.toLocaleString("en-US") .

Running Your Code


Enter the following in the terminal:

node back-to-school.js

Testing Your Code


How will you know if your code works? Change the value of education and re-run the
code.

Salary Education

$25,636 no high school diploma

$35,256 high school diploma

$41,496 Associate's degree

$59,124 Bachelor's degree


Salary Education

$69,732 Master's degree

$89,960 Professional degree

$84,396 Doctoral degree

Key Points to Remember


As you face new challenges and complex problems, remember what you
learned in this lesson about using logic to create algorithms:

 Break the problem down into smaller steps


 Use conditional statements and logical operators to tell your code when and
how to run

We Covered A Lot in This Lesson!


You now know how to:

 Write if...else and else...if conditionals


 Use logical operators to handle more complex logic
 Identify truthy and falsy values
 Use ternary operators for more concise conditional logic
 Use a switch statement to chain multiple else if statements

Great work!
Loops Repeat Blocks of Code
Conditional statements are one way to control the flow of code -- if a certain condition is
true, execute this block of code, otherwise, execute that other block of code.

Loops are another way to control the flow of code by allowing us to execute a block of
code multiple times.

What We Will Cover in This Lesson


You will learn how to:

 Use while loops


 Use for loops
 Nest loops for more complex automation
 Use assignment operators to write more concise code

Along the way we'll give you a lot of practice writing loops.

Let's get started!

The Power of Loops


Here is the naive code we wrote to count to 10,000:

let x = 1;

console.log(x + " mississippi!"); // 1 missippi!

x = x + 1;

console.log(x + " mississippi!"); // 2 missippi!

x = x + 1;

console.log(x + " mississippi!"); // 3 missippi!

.
.

Prints:
1 missippi!
2 missippi!
3 missippi!
and so on...

This works, but it is very time consuming. There has to be a better way!

Loops to the Rescue!


Using a loop will let us iterate over values and repeatedly run a block of code.

Example: a while loop

let x = 1;
while (x <= 10000) {
console.log(x + " mississippi!");
x = x + 1;
}

Why does the video use var and the example code
use let ?

Although var works, it is now considered best practice to use let or const instead.
We're showing you both but you should try to use let and const in your own code.

Parts of a while Loop


There are many different kinds of loops, but they all essentially do the same thing: they
repeat an action some number of times.

Three main pieces of information that any loop should have are:
1. When to start: The code that sets up the loop — defining the starting value of
a variable for instance.
2. When to stop: The logical condition to test whether the loop should continue.
3. How to get to the next item: The incrementing or decrementing step — for
example, x = x * 3 or x = x - 1

Here's a basic while loop example that includes all three parts.

let start = 0; // when to start

while (start < 10) { // when to stop

console.log(“start = ”, start);

start = start + 2; // how to get to the next item

Prints:
start = 0
start = 2
start = 4
start = 6
start = 8
If a loop is missing any of these three things, then you might find yourself in trouble. For
instance, a missing stop condition can result in a loop that never ends!

⚠️Don't run this code! ⚠️

while (true) {

console.log("true is never false, so I will never stop!");

If you did try to run that code in the console, you would probably crash your browser
tab.

WARNING: You’re probably reading this because you didn't heed our warnings about
running that infinite loop in the console. If your browser tab has crashed or has become
frozen/unresponsive, there are a couple ways to fix this. If you are using Firefox, the
browser will popup a notification about your script being unresponsive, and will give you
the option to kill the script (do that). If you're using Chrome, go to the taskbar and select
Window > Task Manager. You can end the process for the particular tab you ran the
script in through the task manager. If you’re not using Firefox or Chrome, download
Firefox or Chrome ;).
An infinite loop will run forever... until your browser crashes or you stop this video 😉
Note - This video does not have an audio. It was created as a visual to aid learning.

Here's an example where a loop is missing how to get to the next item; the variable x is never
incremented. x will remain 0 throughout the program, so the loop will never end.

⚠️Don't run this code! ⚠️

let x = 0;

while (x < 1) {

console.log('Oops! x is never incremented from 0, so it will


ALWAYS be less than 1');

This code will also crash your browser tab, so we don't recommend running it.

Question 1 of 2
How many times will the while loop run?

let x = 10;
while (x <= 25) {
console.log('Printing out x = ' + x);
x = x + 2;
}

15

Question 2 of 2
Here's a while loop that is supposed to print out the values of x from 0 to 5, but
there's a bug. What is missing? Hint: there may be more than one correct
response.

while (x < 6) {
console.log('Printing out x = ' + x);
}

Quiz: JuliaJames
LessonDownloads

"Fizzbuzz" is a famous interview question used in programming interviews. It goes


something like this:

 Loop through the numbers 1 to 100


 If the number is divisible by 3, print "Fizz"
 If the number is divisible by 5, print "Buzz"
 If the number is divisible by both 3 and 5, print "FizzBuzz"
 If the number is not divisible by 3 or 5, print the number

TIP: A number x is divisible by a number y if the answer to x / y has a remainder of


0. For example, 10 is divisible by 2 because 10 / 2 = 5 with no remainder. You can
check if a number is divisible by another number by checking if x % y === 0 .
We're going to have you program your own version of FizzBuzz called "JuliaJames"
(yes, imaginative, right?) Keep in mind that in an interview, you would want to write
efficient code with very little duplication. We don't want you to worry about that for this
question. Just focus on practicing using loops.

Directions:
Write a while loop that:

 Loop through the numbers 1 to 20


 If the number is divisible by 3, print "Julia"
 If the number is divisible by 5, print "James"
 If the number is divisible by 3 and 5, print "JuliaJames"
 If the number is not divisible by 3 or 5, print the number

Running Your Code


Enter the following in the terminal:

node julia-james.js
Node.js(opens in a new tab) is an open-source backend JavaScript runtime
environment. That basically means that it will run your JavaScript code in the terminal
and return any output that is generated. We'll be using Node to run the code in our
workspaces for many of the quizzes in this course.

Testing Your Code


Your code should log out the following in the terminal:

1
2
Julia
4
James
Julia
7
8
Julia
James
11
Julia
13
14
JuliaJames
16
17
Julia
19
James
⚠️These workspaces will autosave your code -- but it can take a few seconds.
If you try to run your code before the autosave occurs, you might see an error like this:
ReferenceError: Cannot access 'variableName' before initialization
Wait a few seconds and try to run the code again.
Try the quiz on your own first. If you get stuck you can check the solution by clicking the
button below.

Show Solution

Quiz: 99 Bottles of Juice


LessonDownloads

Directions:
Write a loop that prints out the following song. Starting at 99, and ending at 1 bottle.

99 bottles of juice on the wall! 99 bottles of juice!


Take one down, pass it around... 98 bottles of juice on
the wall!

98 bottles of juice on the wall! 98 bottles of juice!


Take one down, pass it around... 97 bottles of juice on
the wall!

...

2 bottles of juice on the wall! 2 bottles of juice! Take


one down, pass it around... 1 bottle of juice on the
wall!

1 bottle of juice on the wall! 1 bottle of juice! Take


one down, pass it around... 0 bottles of juice on the
wall!

Attention to Detail is Important in Coding!


Pay attention to the pluralization of the word "bottle" when you go from 2 bottles to
1 bottle to 0 bottles.

It may not seem critical in this code, but what if you were coding a message to be sent
out to important customers? Using incorrect pluralization might cause them to question
your organization's competence and ability to meet their needs.

Running Your Code


Enter the following in the terminal:

node juice.js

Your code should print out the song lyrics above. Double check the last three links to
make sure you use the correct pluralization of "bottles" for each verse of the song.

Quiz: Countdown, Liftoff!


LessonDownloads

NASA's countdown to launch includes checkpoints(opens in a new tab) where NASA


engineers complete certain technical tasks. During the final minute, NASA has 6 tasks
to complete:

 Orbiter transfers from ground to internal power (T-50 seconds)


 Ground launch sequencer is go for auto sequence start (T-31 seconds)
 Activate launch pad sound suppression system (T-16 seconds)
 Activate main engine hydrogen burnoff system (T-10 seconds)
 Main engine start (T-6 seconds)
 Solid rocket booster ignition and liftoff! (T-0 seconds)

NOTE: "T-50 seconds" read as "T-minus 50 seconds".

Directions:
Write a while loop that counts down from 60 seconds and:
 If there's a task being completed, it prints out the task
 If there is no task being completed, it prints out the time as T-x seconds

Use the task and time descriptions described above.

Running Your Code


Enter the following in the terminal:

node liftoff.js
Your output should look like the following:

T-60 seconds
T-59 seconds
T-58 seconds
...
T-51 seconds
Orbiter transfers from ground to internal power
T-49 seconds
...
T-3 seconds
T-2 seconds
T-1 seconds
Solid rocket booster ignition and liftoff!

Loop Basics
A loop should always include:

 Where to start
 When to stop
 How to get to the next item

It's easy to forget some of these pieces in a while loop and end up with an
infinte loop that crashes your browser!

for loops give you more control over the looping process.
for Loops Require a Start, Stop and Step
The for loop explicitly forces you to define the start point, stop point, and
each step of the loop. In fact, you'll get an Uncaught SyntaxError:
Unexpected token ) if you leave out any of the three required pieces.

for ( start; stop; step ) {

// do this thing

Here's an example of a for loop that prints out the values from 0 to 5. Notice
the semicolons separating the different statements of the for loop: var i = 0; i
< 6; i = i + 1

for (let i = 0; i < 6; i = i + 1) {

console.log("Printing out i = " + i);

Prints:
Printing out i = 0
Printing out i = 1
Printing out i = 2
Printing out i = 3
Printing out i = 4
Printing out i = 5

How the Loop is Interpreted


i i<6 console.log output

0 true Printing out i = 0


i i<6 console.log output

1 true Printing out i = 1

2 true Printing out i = 2

3 true Printing out i = 3

4 true Printing out i = 4

5 true Printing out i = 4

6 false

Nested Loops Add Complexity


Nested loops are just loops inside of other loops. Take a look at our demo code:

for (let x = 0; x < 3; x = x + 1) {

for (let y = 0; y < 2; y = y + 1) {

console.log(x + ", " + y);

This is how the loop is interpreted in the browser:


x x<3 y y<2 console.log output

0 true 0 true 0, 0

0 true 1 true 0, 1

0 true 2 false

1 true 0 true 1, 0

1 true 1 true 1, 1

1 true 2 false

2 true 0 true 2, 0

2 true 1 true 2, 1

2 true 2 false

3 false

Try It Yourself!
Paste this nested loop in your browser and take a look at what it prints out:
for (let x = 0; x < 5; x = x + 1) {

for (let y = 0; y < 3; y = y + 1) {

console.log(x + "," + y);

Prints:
0, 0
0, 1
0, 2
1, 0
1, 1
1, 2
2, 0
2, 1
2, 2
3, 0
3, 1
3, 2
4, 0
4, 1
4, 2
Notice the order that the output is being displayed.

For each value of x in the outer loop, the inner for loop executes completely. The outer loop
starts with x = 0 , and then the inner loop completes its cycle with all values of y :

x = 0 and y = 0, 1, 2 // corresponds to (0, 0), (0, 1), and (0,


2)

Once the inner loop is done iterating over y , then the outer loop continues to the next value, x
=1 , and the whole process begins again.

x = 0 and y = 0, 1, 2 // (0, 0) (0, 1) and (0, 2)

x = 1 and y = 0, 1, 2 // (1, 0) (1, 1) and (1, 2)


x = 2 and y = 0, 1, 2 // (2, 0) (2, 1) and (2, 2)

etc.

NOTE: Nested loops can be tricky at first. We will revisit them again when we talk
about arrays, which are lists of data. Loops are very helpful when working with arrays.

Quiz Question
What will this loop print out?

for (let i = 0; i <= 6; i = i + 2) {


console.log(i);
}

123456

Increment and Decrement Operators


Increment and decrement operators are shortcuts that are often used in the step part of
a for loop.

Increment Operator
The increment operator ++ adds one a to variable, returns a value and assigns the
incremented value to the variable.

x++ is the postfix operator, which means that it returns the value before incrementing
it:

let x = 2;

x++ //returns 2 then assigns 3 as the value of x

console.log(x); // logs out 3

++x is the prefix operator, which means that it returns the value after incrementing it:

let x = 2;
++x // assigns 31 as the value of x then returns 3

console.log(x); // logs out 3

Try it in the the console!

Decrement Operator
a The decrement operator -- subtracts one from a variable, returns a value and
assigns the decremented value to the variable.

Similiar to the increment operator, x-- is the postfix operator, which means that it
returns the value before incrementing it:

let x = 2;

x-- //returns 2 then assigns 1 as the value of x

console.log(x); // logs out 1

--x is the prefix operator, which means that it returns the value after incrementing it:

let x = 2;

--x // assigns 1 as the value of x then returns 1

console.log(x); // logs out 1

Try it in the the console!

Assignment Operators
An assignment operator is a shorthand way to peform a mathematical operation on a
variable and assigns that value to the variable.

You can use assignment operators for addition, subtraction, multiplication, and division.

// Add y to x

x += y // x = x + y
// Subtract y from x

x -= y // x = x - y

// Multiply x by x

x *= y // x = x* y

// Divide x by y

x /= y // x = x / y

These assignment operators will come in handy as you create more loops!
What does this code log out? javascript let x = 4; x++; console.log(x);

*Enter only the numerical response -- no extra


characters*

Quiz: Changing the Loop


LessonDownloads

Directions:
Rewrite the following while loop as a for loop:

let x = 9;
while (x >= 1) {
console.log("hello " + x);
x = x - 1;
}

Running Your Code


Enter the following in the terminal:
node change.js

Testing Your Code


Make sure you are using a for loop and that you get this output:

hello 9
hello 8
hello 7
hello 6
hello 5
hello 4
hello 3
hello 2
hello 1

Quiz: Fix the Error 1


LessonDownloads

Directions:
Here is a for loop that's supposed to print the numbers 5 through 9. Fix the errors!

for (x < 10; x++) {

console.log(x);

Your Code:

Running Your Code


Enter the following in the terminal:

node fix1.js
Testing Your Code
Make sure you are using a for loop and your code runs without errors. You should get
this output:

5
6
7
8
9

Directions:
The for loop below has an error. Fix it!

for (let k = 12 k < 21 k++) {

console.log(k);

Your Code:

Running Your Code


Enter the following in the terminal:

node fix2.js

Testing Your Code


Make sure you are using a for loop and your code runs without errors. You should get
this output:

12
13
14
15
16
17
18
19
20

Directions:
Write a for (note: not a function) loop that prints out the factorial of the number 12:

A factorial is calculated by multiplying a number by all the numbers below it. For
instance, 3! or "3 factorial" is 3 \ *2 * 1 = 6

3!=3∗2∗1=63!=3∗2∗1=6
4!=4∗3∗2∗1=244!=4∗3∗2∗1=24
5!=5∗4∗3∗2∗1=1205!=5∗4∗3∗2∗1=120
Save your final answer in a variable called solution and print it to the console.

Running Your Code


Enter the following in the terminal:

node factorials.js

Testing Your Code


Make sure you are using a for loop and your code runs without errors. You should get
this output:

479001600
Directions:

Creative Commons - Jeffrey Smith - "State Theater"(opens in a new tab)


Theater seats often display a row and seat number to help theatergoers find their seats.
If there are 26 rows (0 to 25) and 100 seats (0 to 99) in each row, write a
nested for loop to print out all of the different seat combinations in the theater.

Example output for row-seat information: output each row and seat number on a
separate line

0-0
0-1
0-2
...
25-97
25-98
25-99

Running Your Code


Enter the following in the terminal:
node find-seat.js

Testing Your Code


Make sure you are using a for loop and your code runs without errors. Your output
should be simliar to above.

Loops Are a Fundamental Programming Tool


You will be using loops all the time as you progress as a coder. And you
should now be really good at them!

What We Learned in This Lesson


You now know how to:

 Use while loops


 Use for loops
 Nest loops for more complex automation
 Use assignment operators to write more concise code

Next up... functions!

What Are Functions?


Functions are reusable chunks of code.

Functions are very helpful as the problems we need to solve with our code get more
complex. We'll often need to repeat steps on different inputs -- and functions let us do
that!

***Analogy: Microwaving pizza***


The microwave Pizza Reheat button uses a function to calculate the optimal power
level and time to reheat pizza so James doesn't have to calculate the settings from
scratch every time he is hungry.

 The input is the number of slices that need to be reheated


 The output is reheated pizza

What We Will Cover in This Lesson


You will learn how to:

 Declare and run functions


 Use return statements to return items when a function runs
 Explain the difference between parameters and arguments
 Explain the difference between returning and logging
 Understand how scope works in JavaScript
 Use let and const in block scope
 Understand how hosting works
 Store functions in variables using function expressions
 Use inline function expressions

Let's get started!

Functions Are Awesome!


The ability to generalize code for a variety of possible inputs is a powerful tool when
creating easy to understand, non-repetitive code.

function reverseString(reverseMe) {

let reversed = "";

for (let i = reverseMe.length - 1; i >= 0; i--) {

reversed += reverseMe[i];
}

return reversed;

console.log(reverseString("Julia"));

Prints "ailuJ"
Let's break it down:

 The function has one parameter -- a variable named reverseMe .


 reverseMe will store the argument -- the value of the string that we want the
function to operate on.
 The variable reversed is intialized as an empty string. It will be used to store
the reversed string as as it is being constructed.
 The function loops through each character the reverseMe string using string
indexes, from the end to the beginning and adds each character to reversed .
 When the loop is complete, reversed is returned.

Annotated Function
// Set one parameter to hold the value of the input
string

function reverseString(reverseMe) {

// Declare a variable with an empty string to store


the reversed string

let reversed = "";


// Loop through the `reverseMe` string from back to
front

for (let i = reverseMe.length - 1; i >= 0; i--) {

// Add each character to the end of `reversed`

reversed += reverseMe[i];

return reversed;

// Return the completed string when the loop is complete


return reversed; }

console.log(reverseString("Julia"));

Using a function simplifies the process and allows you to reuse the function by calling it
by its name and passing it in a string. If these steps were not wrapped inside
this reverseString function you would to write all of this code each time you needed to
reverse a string.

Free Response

Why does the video use var and the example code
use const ?

Although var works, it is now considered best practice to


use let or const instead. We're showing you both but you should try to
use let and const in your own code.

We'll talk about var , let , and const a bit later in this lesson when we
discuss scope!
How to Declare a Function
Functions allow you to package up lines of code that you can use (and often reuse) in
your programs.

Sometimes they take parameters like the pizza button from the beginning of this
lesson. reheatPizza() had one parameter: the number of slices.

function reheatPizza(numSlices) {

// code that figures out reheat settings!

The reverseString() function that you saw also had one parameter: the string to be
reversed.

function reverseString(reverseMe) {

// code to reverse a string!

In both cases, the parameter is listed as a variable after the function name, inside the
parentheses. And, if there were multiple parameters, you would just separate them with
commas.

function doubleGreeting(name, otherName) {

// code to greet two people!

But, you can also have functions that don't have any parameters. Instead, they just
package up some code and perform some task. In this case, you would just leave the
parentheses empty. Take this one for example. Here's a simple function that just prints
out "Hello!" .

// accepts no parameters! parentheses are empty

function sayHello() {
const message = "Hello!"

console.log(message);

If you tried pasting any of the functions above into the JavaScript console, you probably
didn't notice much happen. In fact, you probably saw undefined returned back to
you. undefined is the default return value on the console when nothing
is explicitly returned using the special return keyword.

Return Statements
In the sayHello() function above, a value is printed to the console with console.log ,
but not explicitly returned with a return statement. You can write a return statement by
using the return keyword followed by the expression or value that you want to return.

// declares the sayHello function

function sayHello() {

const message = "Hello!"

return message; // returns value instead of printing it

How to Run a function


Now, to get your function to do something, you have to invoke or call the function using
the function name, followed by parentheses with any arguments that are passed into it.
Functions are like machines. You can build the machine, but it won't do anything unless
you also turn it on. Here's how you would call the sayHello() function from before, and
then use the return value to print to the console:

// declares the sayHello function

function sayHello() {
const message = "Hello!"

return message; // returns value instead of printing it

// function returns "Hello!" and console.log prints the return value

console.log(sayHello());

Prints: "Hello!"

Parameters vs. Arguments


At first, it can be a bit tricky to know when something is either a parameter or an
argument. The key difference is in where they show up in the code. A parameter is
always going to be a variable name and appears in the function declaration. On the
other hand, an argument is always going to be a value (i.e. any of the JavaScript data
types - a number, a string, a boolean, etc.) and will always appear in the code when the
function is called or invoked.

Try declaring and calling some functions on your own:

Question 1 of 2
Use the following function to answer this question.

function findAverage(x, y) {

const answer = (x + y) / 2;

return answer;
}

const avg = findAverage(5, 9);


What You’ve Learned So Far:
 Functions package up code so you can easily use (and reuse) a block of
code.
 Parameters are variables that are used to store the data that's passed into a
function for the function to use.
 Arguments are the actual data that's passed into a function when it is
invoked:

// x and y are parameters in this function declaration

function add(x, y) {

// function body

// Here, `sum` variable has a scope within the


function.

// Such variables defined within a function are called


Local variables

// You can try giving it another name

const sum = x + y;

return sum; // return statement

// 1 and 2 are passed into the function as arguments,

// and the result returned by the function is stored in a


new variable `sum`

// Here, `sum` is another variable, different from the


one used inside the function

const sum = add(1, 2);

The function body is enclosed inside curly brackets:


function add(x, y) {

// function body!

Return statements explicitly make your function return a value:

return sum;

You invoke or call a function to have it do something:

add(1, 2);

Returns: 3

Directions:
1. Declare a function called laugh() that returns "hahahahahahahahahaha!" .
2. Print the value returned from the laugh() function to the console. It should
print:

hahahahahahahahahaha!

Running Your Code


Enter the following in the terminal:

node laugh1.js
Node.js(opens in a new tab) is an open-source backend JavaScript runtime
environment. That basically means that it will run your JavaScript code in the terminal
and return any output that is generated. We'll be using Node to run the code in our
workspaces for many of the quizzes in this course.
⚠️These workspaces will autosave your code -- but it can take a few seconds.
If you try to run your code before the autosave occurs, you might see an error like this:
ReferenceError: Cannot access 'variableName' before initialization

Wait a few seconds and try to run the code again.


Directions:
1. Write a function called laugh() that takes one parameter, num .
2. The function should return a string with num number of "ha" s.
3. The string should end with an exclamation point "!" .

TIP: You might need a loop to solve this!


Here's an example of the output and how to call the function that you will write:

console.log(laugh(3));

Prints: "hahaha!"

Running Your Code


Enter the following in the terminal:

node laugh2.js

Testing Your Code


How will you know if your code works? When you run the code your output should look
like this:

hahaha!
hahahaha!
hahahahahahahaha!

Test Your Intuition


Before watching the video below, look at the code in the quizzes below. What do you
think will be printed when the code is run?

Don't worry if your guess is wrong! We'll explore what is happening with logging and
return values in the video.
Question 1 of 5
What do you think will be printed when this code is run?

function whatHappens() {
console.log("I am printing to the console");
return "I am returning a value";
}

whatHappens();

Question 2 of 5
What do you think will be printed when this code is run?
Notice that in this code we are wrapping our function call
in console.log statement.

function whatHappens() {
console.log("I am printing to the console");
return "I am returning a value";
}

console.log(whatHappens());

Output from a Function


There are two ways to get output from a function:

1. console.log is used to print a value to the JavaScript console.


2. The return keyword is used to stop execution of a function and *return the
value back to the caller.

Points to Remember About Returning and Printing


 Returning is different from printing
Printing a value to the JavaScript console only displays the value but the value can't be
used anywhere else.

 Printing is great for debugging code

Using console.log to test your code in the JavaScript console or to print out values as
your code runs can be extremely helpful in pinpointing where something has gone
wrong in your code.

 All function calls return something

If a return value is not specified, the function will return undefined .

 The return keyword will stop the execution of a function

Any code after a return statement will be ignored.


Demo Code: Function to determine if a number is a prime number

Math Review:
A prime number is an integer that is not a product of two smaller integers.
The modulo operator(opens in a new tab) % returns the remainder left over when
one operand is divided by a second operand.
You can check for prime numbers by dividing them by smaller integers. If the number
can be divided without remainder by any integer greater than 1 it is not a prime number.
function isPrime(integer) {
for (let x = 2; x < integer; x++ ) {
if(integer % x === 0) {
console.log(integer + " is divisible by " +
x);
return false
}
}

return true
}
Exploring console.log and return Statements
Paste the following function declaration and function invocation into the JavaScript
console to see the difference between logging (printing) and returning:

function isThisWorking(input) {

console.log("Printing: isThisWorking was called and " +


input + " was passed in as an argument.");

return "Returning: I am returning this string!";

isThisWorking(3);

Prints: "Printing: isThisWorking was called and 3 was passed in as an argument"


Returns: "Returning: I am returning this string!"
If you don't explicitly define a return value, the function will return undefined by
default.

function isThisWorking(input) {

console.log("Printing: isThisWorking was called and " +


input + " was passed in as an argument.");

isThisWorking(3);

Prints: "Printing: isThisWorking was called and 3 was passed in as an argument"


Returns: undefined

Question 3 of 5
What does this function "return"?

function sleep() {
console.log("I'm sleepy!");
return "zzz";
return "snore";
}

sleep();

"I'm sleepy!"

"zzz"

"snore"

"zzz"
"snore"
Submit

Question 4 of 5
What number will be printed (to the JavaScript console)?

function square(x) {
return x * x;
}

function subtractFour(x) {
return square(x) - 4;
}

console.log(subtractFour(5));

25

21

5
Submit

Question 5 of 5
What do you think will happen with the following code?

function test() {
return 1;
return 2;
}

test();

1 will be returned
2 will be returned
3 will be returned

error
Using Return Values
Returning a value from a function is great, but what's the use of a return value if you're
not going to use the value to do something?

A function's return value can be stored in a variable or reused throughout your program
as a function argument.

Example
Here, we have a function that adds two numbers together, and another function that
divides a number by 2. We can find the average of 5 and 7 by using the add() function
to add a pair of numbers together, and then by passing the sum of the two
numbers add(5, 7) into the function divideByTwo() as an argument.

And finally, we can even store the final answer in a variable called average and use the
variable to perform even more calculations in more places!

// returns the sum of two numbers


function add(x, y) {
return x + y;
}

// returns the value of a number divided by 2


function divideByTwo(num) {
return num / 2;
}

const sum = add(5, 7); // call the "add" function and


store the returned value in the "sum" variable
const average = divideByTwo(sum); // call the
"divideByTwo" function and store the returned value in
the "average" variable

Quiz Question
Try predicting what will be printed in the console.log statement below. Then,
check your prediction by pasting the code into the JavaScript console. Functions
can be tricky, so try figuring it out before running the code!

function addTen(x) {
return x + 10;
}

function divideByThree(y) {
return y / 3;
}

const result = addTen(2);


console.log(divideByThree(result));

Understanding Scope
Scope is the part of the program where a particular identifier, such as a
variable or a function name, is visible or accessible.

As a programmer, you'll run into a lot of situations where understanding scope


will be critical to writing effective and error-free code.

***Analogy: Finding a Book***

When James is inside the library he is in scope to find out where the
book Great Expectations is shelved. The librarian has that information is able to
share it with James.

When James is outside of the library, the person he asked about Great
Expectations didn't have any information about library or the books inside of it.
In this case, James's question is out of scope.
The Three Types of Scope in JavaScript
JavaScript has three types of scope.

 global scope
 function scope
 block scope

The first two are pretty simple:

 Variables declared in the global scope are accessible to any other part of the
program.
 Variables declared inside a function are in the function scope which means
they are only accessible inside that function.

Block scope is more complicated. We'll learn more about that later in this lesson.

Translating the Library Example to Code


Let's translate James's requests for a book into JavaScript code so we can take a closer
look at the scope:

const bookSeeker = "James";

const book = "Great Expectations";

function library() {

const librarian = "Julia";

console.log(bookSeeker + " asked " + librarian + " for " +


book);

function classicLiterature() {

const shelf = "Dickens";

console.log( bookSeeker + " found " + book + " on the " +


shelf + " shelf!");
}

classicLiterature();

Global Scope
bookSeeker and book are in the global scope so as expected, we can use access
them anywhere in the code.

For example, this code runs without an error:

console.log(bookSeeker + " is looking for " + book);

Prints James is looking for Great Expectations


We can also run the library function without an error:

library();

Prints
James asked Julia for Great Expectations
James found Great Expectations on the Dickens shelf!

Function Scope
What happens when we try to access the librarian variable declared inside
the library function from the console? We get an error, because librarian can only
be accessed inside the scope of the library function.

console.log(librarian);

Returns Uncaught ReferenceError: librarian is not defined


We get a similar error when we try to access shelf in the console because
the shelf variable is declared inside the classicLiterature function.

console.log(shelf);
Returns Uncaught ReferenceError: shelf is not defined

Question 1 of 4
Which of these variables a , b , c , and d , are defined in the global scope?

const a = 1;
function x() {
const b = 2;
function y() {
const c = 3;
function z() {
const d = 4;
}
z();
}
y();
}

x();

c
d
Submit

Question 2 of 4
Which of these variables a , b , c , and d , are defined in the scope of
function x ?

const a = 1;
function x() {
const b = 2;
function y() {
const c = 3;
function z() {
const d = 4;
}
z();
}
y();
}

x();

a
b

d
Submit

Question 3 of 4
Which of these variables a , b , c , and d , are defined in the scope of
function y ?

const a = 1;
function x() {
const b = 2;
function y() {
const c = 3;
function z() {
const d = 4;
}
z();
}
y();
}

x();
a

d
Submit

Question 4 of 4
Which of these variables a , b , c , and d , are defined in the scope of
function z ?

const a = 1;
function x() {
const b = 2;
function y() {
const c = 3;
function z() {
const d = 4;
}
z();
}
y();
}
x();

d
Submit

How Does Javascript Find a Variable? It Uses the


Scope Chain
When the JavaScript engine is looking for a variable, it starts from the current
scope and moves outward:

1. The JavaScript engine will start looking in the scope where the variable is
requested.
2. If it can't find it in the current scope, it moves out one level and checks again.
3. It keeps moving to the outer scope until it has reached the global scope.
4. If the JavaScript engine checks all of the outer functions and global scope,
and it still can't find the identifier then it will return a Reference error.
// <-- 4. JavaScript engine looks here last
const globalVar = "I am in the global scope";

function outerOuterFunction() {
// <-- 3. JavaScript engine looks here third
const outerOuterVar = 'I am in the outerOuterFunction scope';
function outerFunction() {
// <-- 2. JavaScript engine looks here second
const outerVar = 'I am in the outerFunction scope';
function innerFunction() {
// <-- 1. JavaScript engine looks here first
const innerVar = 'I am in the innerFunction scope';
console.log(globarVar);
}
}
}

uestion 2 of 2
Where can you print out the value of variable d without an error?

const a = 1;
function x() {
const b = 2;
function y() {
const c = 3;
function z() {
const d = 4;
}
z();
}
y();
}

x();

anywhere in the script!

anywhere inside function x()

anywhere inside function y()

anywhere inside function z()


Submit
A New Type of Scope
With the ES6 version of JavaScript, a new type of scope was created: block scope which limits
the scope of a variable to the block of code where it is declared.

What is a Block?
A block is a group of statements in between curly braces. You've seen blocks in conditional
statements:

const x = 5;

if (x < 6) {

const double = x * 2;

console.log(double);

} else {

const half = x / 2;

console.log(half);

and in loops:

for (let i = 0; i < 5; i++) {

let triple = x * 3;

console.log(triple);

In the examples above, the variables double , half and triple are only available inside the
block where they are declared.

Question 1 of 4
What will print out to the console when this code is run?

let fruit = "apple";


if (fruit !== "banana") {
let fruit = "banana";
console.log(fruit);
}
console.log(fruit);
apple
apple

banana
apple
banana
banana

Block Scope Only Works with let And const


Unlike with function scope, if you declare a variable inside a block using var the variable will be
accessible both inside the block and in the block's outer scope.

Question 2 of 4
What will print out to the console when this code is run?

var fruit = "apple";

if (fruit !== "banana") {


var fruit = "banana";
console.log(fruit);
}
console.log(fruit);

apple
apple

banana
apple

What will print out when you run this code?

if (true) {
var x = "x is accessible";
let y = 'y is accessible';
const z = 'z is accessible';
console.log("Inside the if block scope:");
console.log(x);
console.log(y);
console.log(z);
}
console.log("Outside the if block scope:")
console.log(x);
console.log(y);
console.log(z);
What will print out when you run this code?

function whereAmIAssessible(a) {
if (a) {
var x = "x is accessible";
let y = 'y is accessible';
const z = 'z is accessible';
console.log("Inside the if block scope:");
console.log(x);
console.log(y);
console.log(z);
}
}

whereAmIAssessible(true);
console.log("Outside the function scope:")
console.log(x);
console.log(y);
console.log(z);

When Should I Use var Instead of let or const ?


NEVER!

You might be wondering:

"Why wouldn't I always use global variables? Then, I would never need to use function
arguments since ALL my functions would have access to EVERYTHING!"
Well... Global variables might seem like a convenient idea at first, especially
when you're writing small scripts and programs, but there are many reasons
why you shouldn't use them unless you have to. For instance, global variables
can conflict with other global variables of the same name. Once your
programs get larger and larger, it'll get harder and harder to keep track and
prevent this from happening.

There are also other reasons you'll learn more about in more advanced
courses. But for now, just work on minimizing the use of global variables as
much as possible.

💡 Always use let and const instead of var .

Scope Can Be Tricky!


Scope can be a tricky subject, especially when you're working in both global and
function scope.

Shadowing occurs when variables in different scopes have the same name. When this
happens the variable in the inner scope overrides the variable in the outer scope.

Example: scope shadowing

let bookTitle = "Le Petit Prince";

console.log(bookTitle);

function displayBookEnglish() {

bookTitle = 'The Little Prince';

console.log(bookTitle);

displayBookEnglish()
console.log(bookTitle);

Prints
Le Petit Prince
The Little Prince
The Little Prince

Best Practice: Declare a New Variable


To avoid scope override, always declare a new variable inside your function. This
prevents JavaScript from reassigning the value of the variable in the outer scope.

Example: no shadowing

let bookTitle = "Le Petit Prince";

console.log(bookTitle);

function displayBookEnglish() {

let bookTitle = 'The Little Prince';

console.log(bookTitle);

displayBookEnglish()

console.log(bookTitle);

Prints
Le Petit Prince
The Little Prince
Le Petit Prince

Question 1 of 2
Without pasting into your console, what do you think this code will print out?
let x = 1;

function addTwo() {
x = x + 2;
}

addTwo();
x = x + 1;
console.log(x);

4
Submit

Question 2 of 2
Without pasting into your console, what do you think this code will print out?
var x = 1;

function addTwo() {
var x = x + 2;
}

addTwo();
x = x + 1;
console.log(x);

4
Submit

You may be wondering... Why are we using var in the second quiz?
Great question! There are some interesting implications of block scoping that we will
cover later in the lesson. If you want a preview, try replacing var with let and see
what happens when you run the code. We'll explore this more when we look into
hoisting.

What You’ve Learned So Far:


 If an identifier is declared in global scope, it's available everywhere.
 If an identifier is declared in function scope, it's available in the function it was
declared in (even in functions declared inside the function).
 If an identifier is declared in block scope with var , it is available in the block
and in the outer scope of the block it was declared in.

 If an identifier is declared in block scope with let or const , it is only


available in the block it was declared in.
 When trying to access an identifier, the JavaScript Engine will first look in the
current function. If it doesn't find anything, it will continue to the next outer
function to see if it can find the identifier there. It will keep doing this until it
reaches the global scope.
 Global identifiers are a bad idea. They can lead to bad variable names,
conflicting variable names, and messy code.
 Once you know how to declare a function, a whole new set of possibilities will
open up to you.
 For instance, remember how you can store anything you want in a variable?
Well, in JavaScript, you can also store functions in variables. When a function is
stored inside a variable it's called a function expression.
 const catSays = function(max) {

 let catMessage = "";

 for (let i = 0; i < max; i++) {

 catMessage += "meow ";

 }

 return catMessage;
 };

 Notice how the function keyword no longer has a name.


 const catSays = function(max) {

 // code here

 };

 It's an anonymous function, a function with no name, and you've stored it in a


variable called catSays .
 And, if you try accessing the value of the variable catSays , you'll even see the
function returned back to you.
 catSays;

 Returns:
 function(max) {
 let catMessage = ""
 for (let i = 0; i < max; i++) {
 catMessage += "meow ";
 }
 return catMessage;
 }

 Function Expressions vs Function


Declarations
 Deciding when to use a function expression and when to use a function
declaration can depend on a few things, and you will see some ways to use them
in the next section. But, one thing you'll want to be careful of is hoisting. We'll
look at that next.

Hoisting
Sometimes your JavaScript code will produce errors that may seem
counterintuitive at first. Hoisting is another one of those topics that might be
the cause of some of these tricky errors you're debugging.

Hoisting is a result of how JavaScript is interpreted by your browser.


Essentially, before any JavaScript code is executed, all function declarations
and variables declared with var are hoisted, which means they're raised to
the top of the function scope.

Let's take a look at an example:

JavaScript is Different!
In most programming languages, you have to declare a function or variable before you
can call it.

Intuitively, you might think "This code shouldn't work!" because we're trying to
call findAverage before it is declared:
findAverage(5, 9);

function findAverage(x, y) {

var answer = (x + y) / 2;

return answer;
}

But, surprisingly it does work!

Returns 7
in JavaScript we can call a function before we declare it due to hoisting. Before any
JavaScript code is executed, all function declarations and variables declared
with var are hoisted to the top of their current scope.

So even though the code you write doesn't change, the JavaScript engine interprets it
as if you wrote it this way:

function findAverage(x, y) {

var answer = (x + y) / 2;

return answer;
}

findAverage(5, 9);

Demo Code
Hosting can lead to odd results.

As expected, this code returns a reference error because we haven't


defined greeting anywhere:

function sayGreeting() {
console.log(greeting);

sayGreeting()

Returns Uncaught ReferenceError: greeting is not defined


To get rid of the error, we can define greeting anywhere inside
the sayGreeting function, even after we call it:

function sayGreeting() {

console.log(greeting);

var greeting;
}

sayGreeting()

Returns undefined
We don't get an error, but we do get undefined . Can we fix this by assigning a value
to greeting when we declare it? No. This code still returns undefined :

function sayGreeting() {

console.log(greeting);

var greeting = "hello";

sayGreeting()

Returns undefined
This is because with hoisting, the variable declaration is being hoisted to the top of the
function, but the value of greeting isn't assigned until after the console.log statement
is run. JavaScript is interpreting the code as if it were written like this:
function sayGreeting() {

var greeting;

console.log(greeting);

greeting = "hello";

sayGreeting()

Returns undefined
To avoid bugs like this, declare your functions at the top of your scripts and declare and
assign your variables at the top of your functions.

function sayGreeting() {

var greeting = "hello";

console.log(greeting);

greeting
}

sayGreeting()

Prints Hello

Check Your Understanding


Before we move on, do these quizzes to make sure you understand hoisting.

Question 1 of 3
What value will be printed to the console?

sayHi("Julia");
function sayHi(name) {
console.log(greeting + " " + name);
var greeting;
}

Uncaught ReferenceError

undefined

Julia

undefined Julia

null

null Julia

NaN

NaN Julia

Hello Julia
Submit

Question 2 of 3
What value will be printed to the console?

sayHi("Julia");

function sayHi(name) {
console.log(greeting + " " + name);
var greeting = "Hello";
}

Uncaught ReferenceError

undefined

Julia

undefined Julia

null

null Julia

NaN

NaN Julia

Hello Julia
Submit

Question 3 of 3
What value will be printed to the console?

function sayHi(name) {
var greeting = "Hello";
console.log(greeting + " " + name);
}

sayHi("Julia");
Uncaught ReferenceError

undefined

Julia

undefined Julia

null

null Julia

NaN

NaN Julia

Hello Julia

More About Hoisting


LessonDownloads

What About Function Expressions?


Function expressions are not hoisted, since they involve variable assignment, and
only variable declarations are hoisted. The function expression will not be loaded until
the interpreter reaches it in the script.

Example: Function Expressions vs Function Declarations


The function expression meow is not hoisted so this code throws an error:
function cat() {

console.log(meow(2));

const meow = function (max) {

let catMessage = '';

for (let i = 0; i < max; i++) {

catMessage = 'meow ';

return catMessage;

};

function purr() {

return 'purrrr!';

cat();

Returns Uncaught ReferenceError: Cannot access 'meow' before initialization


The function declaration purr is hoisted so this code runs without error:

function cat() {

console.log(purr());

const meow = function (max) {

let catMessage = '';

for (let i = 0; i < max; i++) {

catMessage = 'meow ';


}

return catMessage;

};

function purr() {

return 'purrrr!';

cat();

Prints purrrr!

Hoisting Is Another Reason to


Use let and const Instead of var !
Variables declared with let and const eliminate the issue of variable hoisting
because they’re scoped to the block, not to the function.

When a variable is declared using let or const inside a block of code (denoted by
curly braces { } ), the variable is stuck in the temporal dead zone until the variable’s
declaration is processed. This sounds scary, but it basically means that the code cannot
access the variable before it has been declared. If you try, you'll get a Reference Error.

Question 1 of 3
What will happen when you run this code?

function getClothing(isCold) {
if (isCold) {
var freezing = 'Grab a jacket!';
} else {
var hot = 'It’s a shorts kind of day.';
console.log(freezing);
}
}

getClothing(false)

Uncaught ReferenceError: freezing is not defined

Grab a jacket!

undefined

It's a shorts kind of day.


Submit

Question 2 of 3
What will happen when you run this code?

function getClothing(isCold) {
if (isCold) {
const freezing = 'Grab a jacket!';
} else {
const hot = 'It’s a shorts kind of day.';
console.log(freezing);
}
}

getClothing(false)

Uncaught ReferenceError: freezing is not defined

Grab a jacket!

undefined

It's a shorts kind of day.


Submit

Question 3 of 3
What will be returned when you run this code?

let x = 1;

function addTwo() {
let x = x + 2;
}

addTwo();
x = x + 1;
console.log(x);

2
3

Uncaught ReferenceError: Cannot access 'x' before initialization


Submit

Hoisting Recap
LessonDownloads

What You’ve Learned So Far:


 JavaScript hoists function declarations and variables declared with var to the top of
the current scope.
 Hoisting doesn't happen when variables are declared with let or const .
 Variable assignments are not hoisted so function expressions are not hoisted.

Best Practices
 Declare functions and variables at the top of your scripts, so the syntax and
behavior are consistent with each other.
 Use let and const to declare variables. You may see var in legacy code,
but do not use it in any new code you are writing.

Build a Triangle
LessonDownloads
Directions:
For this quiz, you're going to create a function called buildTriangle() that will accept
an input (the triangle at its widest width) and will return the string representation of a
triangle. See the example output below.

buildTriangle(10);

Returns:

* *

***

*** *

*** * *

*** ***

*** *** *

*** *** * *

*** *** ***

* * * * * * * * * *

We've given you one function makeLine() to start with. The function takes in a line
length, and builds a line of asterisks and returns the line with a newline character.

function makeLine(length) {

var let = "";

for (let j = 1; j <= length; j++) {

line += "* "

}
return line + "\n";

You will need to call this makeLine() function in buildTriangle() .

Think It Through!
This will be the most complicated program you've written yet, so take some
time thinking through the problem before diving into the code. What tools will you need
from your JavaScript tool belt? Professionals plan out their code before writing anything.
Think through the steps your code will need to take and write them down in order. Then
go through your list and convert each step into actual code. Good luck!

Running Your Code


Enter the following in the terminal:

node triangle.js

Testing Your Code


Change the parameter in the testing code to confirm that your program works for
different values of length .

For console.log(buildTriangle(3)); the output should be:

* *

***

If you try with console.log(buildTriangle(6)); the following should be logged into the
console:

* *
** *

*** *

*** * *

*** ***

Lastly, console.log(buildTriangle(10)); should log out:

*
* *
** *
*** *
*** * *
*** ***
*** *** *
*** *** * *
* * * * * * * * *
* * * * * * * * * *

Functions as Parameters
Being able to store a function in a variable makes it really simple to pass the function
into another function. A function that is passed into another function is called
a callback. Let's say you had a helloCat() function, and you wanted it to return
"Hello" followed by a string of "meows" like you had with catSays . Well, rather than
redoing all of your hard work, you can make helloCat() accept a callback function,
and pass in catSays .

// function expression catSays

const catSays = function(max) {

let catMessage = "";

for (let i = 0; i < max; i++) {

catMessage += "meow ";


}

return catMessage;
};

// function declaration helloCat accepting a callback

function helloCat(callbackFunc) {

return "Hello " + callbackFunc(3);

// pass in catSays as a callback function

helloCat(catSays);

Returns 'Hello meow meow meow '

Named Function Expressions


Show TranscriptSummarize Video

You can create a function expression with a named function, like this:

const favoriteMovie = function movie() {

return "The Fountain";

};

But you still need to use its assigned identifier to call it:

favoriteMovie();

Returns 'The Fountain'


If you try to use the function name to call the function you'll get an error:

movie();
Returns Uncaught ReferenceError: movie is not defined

Inline Function Expressions


A function expression is when a function is assigned to a variable. And, in JavaScript,
this can also happen when you pass a function inline as an argument to another
function. Take the favoriteMovie example for instance:

// Function expression that assigns the function displayFavorite

// to the variable favoriteMovie

const favoriteMovie = function displayFavorite(movieName) {

console.log("My favorite movie is " + movieName);


};

// Function declaration that has two parameters: a function for displaying

// a message, along with a name of a movie

function movies(messageFunction, name) {

messageFunction(name);

// Call the movies function, pass in the favoriteMovie function and name of
movie

movies(favoriteMovie, "Finding Nemo");

Returns: My favorite movie is Finding Nemo


But you could have bypassed the first assignment of the function, by passing the
function to the movies() function inline.

// Function declaration that takes in two arguments: a function for


displaying
// a message, along with a name of a movie

function movies(messageFunction, name) {

messageFunction(name);

// Call the movies function, pass in the function and name of movie

movies(function displayFavorite(movieName) {

console.log("My favorite movie is " + movieName);

}, "Finding Nemo");

Returns: My favorite movie is Finding Nemo


This type of syntax, writing function expressions that pass a function into another
function inline, is really common in JavaScript. It can be a little tricky at first, but be
patient, keep practicing, and you'll start to get the hang of it!

Why Use Anonymous Inline Function Expressions?


Using an anonymous inline function expression might not seem useful at first. Why
define a function that can only be used once and you can't even call it by name?

Anonymous inline function expressions are often used with function callbacks that are
unlikely to be reused elsewhere. Yes, you could store the function in a variable, give it a
name, and pass it in like you saw in the examples above. However, when you know the
function is not going to be reused, it could save you many lines of code to just define it
inline.

For example, we can make the callback function in movies an anonymous inline
function like this:

function movies(messageFunction, name) {


messageFunction(name);
}
movies(function (movieName) {
console.log("My favorite movie is " + movieName);
}, "Finding Nemo");

What You’ve Learned So Far:


Function Expression: When a function is assigned to a variable. The
function can be named, or anonymous. Use the variable name to call a
function defined in a function expression.
// anonymous function expression

const doSomething = function(y) {

return y + 1;

};

// named function expression

const doSomething = function addOne(y) {

return y + 1;

};

// for either of the definitions above, call the function like this:

doSomething(5);

Returns: 6
You can even pass a function into another function inline. This pattern is
commonly used in JavaScript, and can be helpful streamlining your code.
// function declaration that takes in two arguments: a function for
displaying
// a message, along with a name of a movie
function movies(messageFunction, name) {
messageFunction(name);
}

// call the movies function, pass in the function and name of movie
movies(function displayFavorite(movieName) {
console.log("My favorite movie is " + movieName);
}, "Finding Nemo");

Laugh
LessonDownloads

Directions:
Write an anonymous function expression that:

 stores a function in a variable called "laugh"


 creates a string with the number of "ha"s that you pass in as an argument
 adds an exclamation point at the end of the string
 returns the string
laugh(3);

Returns: hahaha!

Running Your Code


Enter the following in the terminal:

node laugh3.js

Testing Your Code


How will you know if your code works? When you run the code your output should look
like this:

ha!
hahahahaha!
hahahahahahahahahaha!
Directions:
Write a named function expression that stores the function in a variable called cry and
returns "boohoo!". Don't forget to call the function using the variable name, not the
function name:

cry();

Returns: boohoo!

Your Code:

Running Your Code


Enter the following in the terminal:

node cry.js

Testing Your Code


How will you know if your code works? When you run the code your output should look
like this:

boohoo!

Directions:
Call the emotions() function so that it prints the output you see below, but instead of
passing the laugh() function as an argument, pass an inline function expression
instead.

emotions("happy", laugh(2)); // you can use your laugh


function from the previous quizzes

Prints: "I am happy, haha!"


Running Your Code
Enter the following in the terminal:

node inline.js

Testing Your Code


How will you know if your code works? Change the value of the argument in
the myFunc call in the emotions function, re-run the code and check the output:

myFunc argument Expected Output

0 I am happy, !

2 I am happy, haha!

7 I am happy, hahahahahahaha!

Functions are Fundamental to Programming!


Congrats on learning how to use functions. We covered a lot in this lesson.
You now know how to:

 Declare and run functions


 Use return statements to return items when a function runs
 Explain the difference between parameters and arguments
 Explain the difference between returning and logging
 Understand how scope works in JavaScript
 Use let and const in block scope
 Understand how hosting works
 Store functions in variables using function expressions
 Use inline function expressions

Arrays Allow Us to Store Lists of Data


In this lesson we'll learn about:

 How to create arrays


 How to use arrays
 How arrays are structured

And we'll be talking a lot about donuts and how to keep track of all of the
donuts in our shop!

Hurray for Arrays!


 An array is a data structure we can use to store multiple values.
 Values in an array are ordered (like a numbered list).
 The numbering of the array order starts at 0 -- not at 1

Building Our Donuts Array


We started with:

const donut1 = "glazed";

const donut2 = "chocolate frosted";

const donut3 = "cinnamon";

const donut4 = "sprinkled";

const donut5 = "powdered";

const donut6 = "cinnamon sugar";


const donut7 = "glazed cruller";

const donut8 = "chocolate cruller";

const donut9 = "cookies";

const donut10 = "Boston creme";

const donut11 = "powdered jelly filled";

const donut12 = "creme de leche";

const donut13 = "glazed donut holes";

const donut14 = "blueberry donut holes";

const donut15 = "cake donut holes";

const donut16 = "chocolate donut holes";

And we created an array like this:

const donuts = [ "glazed", "chocolate frosted", "cinnamon",


"sprinkled", "powdered", "cinnamon sugar", "glazed cruller", "chocolate
cruller", "cookies", "Boston creme", "powdered jelly filled", "creme de
leche", "glazed donut holes", "blueberry donut holes", "cake donut holes",
"chocolate donut holes" ];

Sometimes it is easier to view an array with one item on each line, like this:

const donuts = [ // start of the array

"glazed", // each element separated by a comma

"chocolate frosted",

"cinnamon",

"sprinkled",

"powdered",

"cinnamon sugar",
"glazed cruller",

"chocolate cruller",

"cookies",

"Boston creme",

"powdered jelly filled",

"creme de leche",

"glazed donut holes",

"blueberry donut holes",

"cake donut holes",

"chocolate donut holes"

]; // end of the array

Either way is valid!


Keyboard Shortcut Magic 🪄
James uses a lot of keyboard shortcuts in this video! The keyboard shortcuts are
specific to the editor, as well as the platform you are using. Every editor has its own set
of keyboard shortcuts bound to a particular language. For example, if you are using
Visual Studio Code or Sublime Text as an editor, you can find the default shortcuts
within the editor's menu options.***
***Have fun exploring your code editor's shortcuts!

A Question you may be asking... 🤔


Why does the video use var and the example code use const ?

Great question! While you can use var to declare an array, it is now considered best
practice to use let or const instead. We're showing you both but you should try to
use let and const in your own code.
We'll learn more about why we use const after we learn how to access array elements
using the index.

Arrays
An array is useful because it stores multiple values into a single, organized data
structure. You can define a new array by listing values separated with commas between
square brackets [] .

// creates a new empty array

const emptyArray = [];

// creates a `donuts` array with three strings

const donuts = ["glazed", "powdered", "jelly"];

But strings aren’t the only type of data you can store in an array. You can also store
numbers, booleans… and really anything!

// creates a `mixedData` array with mixed data types

const mixedData = ["abcd", 1, true, undefined, null, "all the things"];

You can even store an array in an array to create a nested array!

// creates a `arraysInArrays` array with three arrays

const arraysInArrays = [[1, 2, 3], ["Julia", "James"], [true, false,


true, false]];

Nested arrays can be particularly hard to read, so it's common to write each nested
array on one line, using a newline after each comma:

const arraysInArrays = [

[1, 2, 3],

["Julia", "James"],
[true, false, true, false]

];

Later in this lesson, we’ll look into some unique situations where nested arrays can be
useful.

Using the Array Constructor


You may also see arrays created this way:

// creates a new empty array

const emptyArray = new Array();

// creates a `donuts` array with three strings

const donuts = new Array("glazed", "powdered", "jelly");

This syntax is valid, but it is preferred to use the literal constructor because the syntax is
simpler and more intuitive.

// creates a new empty array


const emptyArray = [];

// creates a `donuts` array with three strings


const donuts = ["glazed", "powdered", "jelly"];

Quiz Question
Select the valid arrays from the list below.

["pi" "pi" "pi" "pi"]

[33, 91, 13, 9, 23]

[null, "", undefined, []]


[3.14, "pi", 3, 1, 4, "Yum, I like pie!"]

true, 2, "Pie is good!"

[33; 91; 13; 9; 23]

{33, 91, 13, 9, 23}


Submit

Elements and Indexes


 An element is an individual piece of data in an array.
 Each element in the array is numbered, starting with 0 . This number is called
the index.
 The index allows us to access the element's position in the array.

const donuts = [
"glazed", // index is 0
"chocolate frosted", // index is 1
"cinnamon", // index is 2
"sprinkled", // index is 3
"powdered", // index is 4
"cinnamon sugar", // index is 5
"glazed cruller", // index is 6
"chocolate cruller", // index is 7
"cookies", // index is 8
"Boston creme", // index is 9
"powdered jelly filled", // index is 10
"creme de leche", // index is 11
"glazed donut holes", // index is 12
"blueberry donut holes", // index is 13
"cake donut holes", // index is 14
"chocolate donut holes" // index is 15
];
console.log(donuts[11]); // "creme de leche"

Using the Array Index to Access an Element


Remember that elements in an array are indexed starting at position 0 . To access an
element in an array, use the name of the array immediately followed by square brackets
containing the index of the value you want to access.

const donuts = ["glazed", "powdered", "sprinkled"];

console.log(donuts[0]); // "glazed" is the first element


in the `donuts` array

Prints: "glazed"

Accessing a Non-existant Element


One thing to be aware of is if you try to access an element at an index that does not
exist, a value of undefined will be returned.

console.log(donuts[3]); // the fourth element in the


`donuts` array does not exist!

Prints: undefined
Avoid accessing elements outside the bounds of an array. If you try to, the missing
element will be returned back as undefined !

Question 1 of 3
Take a look at the following donuts array.

const donuts = ["glazed", "chocolate frosted", "Boston


cream", "powdered", "sprinkled", "maple", "coconut",
"jelly"];

What line of code would you use to select the "coconut" donut from
the donuts array?
donuts[0]

donuts[4]

donuts[6]

donuts[7]
Submit

Changing the Value of an Array Element


If you want to change the value of an element in array, you can do so by setting it equal
to a new value.

donuts[1] = "glazed cruller"; // changes the second


element in the `donuts` array to "glazed cruller"

console.log(donuts[1]);

Prints: "glazed cruller"


Show TranscriptSummarize Video
Change the value of an element by setting it equal to a new value.

const donuts = ["glazed", "powdered", "sprinkled"];


console.log(donuts[1]); // "powdered"

// change the value of donuts[1]


donuts[1] = "glazed cruller";
console.log(donuts[1]); // "glazed cruller"

Question 2 of 3
We’ve decided to replace some of donuts in the donuts array.

const donuts = ["glazed", "chocolate frosted", "boston


cream", "powdered", "sprinkled", "maple", "coconut",
"jelly"];

donuts[2] = "cinnamon twist";

donuts[4] = "salted caramel";

donuts[5] = "shortcake eclair";

What does the donuts array look like after the following changes?

["glazed", "chocolate frosted", "cinnamon twist", "salted caramel",


"shortcake eclair", "maple", "coconut", "jelly"]
["glazed", "cinnamon twist", "Boston creme", "salted caramel", "shortcake
eclair", "maple", "coconut", "jelly"]

["glazed", "chocolate frosted", "cinnamon twist", "powdered", "salted


caramel", "shortcake eclair", "coconut", "jelly"]

["glazed", "cinnamon twist", "Boston creme", "powdered", "salted caramel",


"shortcake eclair", "coconut", "jelly"]
Submit

Why are we using const instead of let when we declare arrays?


Another great question!

A simple way to think about the difference between let and const is that we
use let when we anticipate that the value of a variable will change and const when
we think it will be constant -- but that shorthand doesn't tell the whole story. The
difference between let and const is not so much about change but
about reassignment

 let allows you to reassign the variable


 const doesn't allow you to reassign the variable

The decision about whether we need to be able to reassign the variable is based on
what type of variable it is and how JavaScript stores those values.
Primitive vs. Object Types in JavaScript
String, Number, Boolean, undefined and null are considered Primitive
Types(opens in a new tab) in JavaScript. These relatively simple data types represent
just one value which makes it easy for JavaScript to store that value. So when you
assign a primitive value to a variable, JavaScript actually assigns that value.

Arrays are more complicated because they consist of a list of values which makes
storage much more complicated. Arrays are actually Object types(opens in a new
tab) which means that instead of assigning all of the values of the list to the array,
JavaScript simply assigns a reference to where to find the values in the array. Even if
the values inside the object change, the reference address doesn't.

Here's an analogy that might help. Think of a JavaScript array as if it were a house. The
house has a group of people who live inside it. If those people move out, and a new
group of people moves in, the names of the people inside the house changes, but the
house's postal address won't.

Test Your Intuition About let and const

Question 3 of 3
Which of these code snippets will throw an error?

const myVar = 2;
myVar = 4;

let myVar = 2;
let myVar = 4;
let myVar = 2;
myVar = ["banana", "apple"];

const myArray = [1, 2, 3, 4];


const myArray = ["banana", "apple"];

const myArray = [1, 2, 3, 4];


myArray = [1, 2, 3, 'banana'];

const myArray = [1, 2, 3, 4];


myArray[3] = "banana";
Submit

TLDR;
We use const to declare arrays because JavaScript is assigning a reference that
points to that array. We can change whatever we want inside the array, but we cannot
change which array the variable points to.
Directions:
Create an array called udaciFamily and add "Julia", "James", and your name to the
array. Then, print the udaciFamily to the console using console.log .

Running Your Code


Enter the following in the terminal:

node udacifamily.js
Node.js(opens in a new tab) is an open-source backend JavaScript runtime
environment. That basically means that it will run your JavaScript code in the terminal
and return any output that is generated. We'll be using Node to run the code in our
workspaces for many of the quizzes in this course.
When your code runs, you should get this output:

Julia
James
Yourname
⚠️These workspaces will autosave your code -- but it can take a few seconds.
If you try to run your code before the autosave occurs, you will see an error like this:
ReferenceError: Cannot access 'variableName' before initialization
Wait a few seconds and try to run the code again.

Building the Crew


LessonDownloads

The space western TV drama Firefly(opens in a new tab) premiered in the United
States on September 20, 2002. Although the show only featured fourteen episodes and
was canceled during its first season, it continues to remain popular today with a growing
fan base. In the show, the captain Mal(opens in a new tab) , played by Nathan
Fillion(opens in a new tab) , leads a crew of renegades on the spaceship Serenity.
Directions:
Create an array called crew to organize the Serenity’s crew and set it equal to the
variables below . You don't need to type out the actual strings, just use the provided
variables.

const captain = "Mal";

const second = "Zoe";

const pilot = "Wash";

const companion = "Inara";

const mercenary = "Jayne";

const mechanic = "Kaylee";

Then, print the crew array to the console.

Running Your Code


Enter the following in the terminal:

node serenity.js
When your code runs, you should get this output:

['Mal', 'Zoe', 'Wash', 'Inara', 'Jayne', 'Kaylee']

Start Workspace

Workspaces will shut down after 30 minutes of inactivity. Any running processes will
be stopped.
Start Workspace

Workspaces may take up to 5 minutes to start.


View Active Workspaces
Try the quiz on your own first. If you get stuck you can check the solution by clicking the
button below.
Show Solution

querySelector
LessonDownloads

Review: Accessing Elements with CSS Selectors


We already reviewed this in a previous section, but let's recap it one more time!

#header {

color: 'red';

.header {

color: 'red';

header {

color: 'red';

Each one of these sets the color to red. The only difference is in the selector; selecting
by ID, selecting by class, and selecting by tag. Got it? Good!
You've already learned the DOM methods to select by ID, class, and tag, too:
 document.getElementById()
 document.getElementsByClassName()

 document.getElementsByTagName()

Three different methods that do almost the exact same thing. Wouldn't it be awesome if
there were a way to do element selecting similar to how CSS does it?

Wait for it - there is!

The querySelector Method


We can use the .querySelector() method to select elements just like we do with CSS.
We use the .querySelector() method and pass it a string that's just like a CSS selector:

// find and return the element with an ID of "header"

document.querySelector('#header');

// find and return the first element with the class "header"

document.querySelector('.header');

// find and return the first <header> element

document.querySelector('header');

Check out the .querySelector() method on MDN: Document.querySelector()(opens in


a new tab)

Demo Recap
In this demo:

1. First, we navigated to the MDN Document.querySelector()(opens in a new


tab) page.
2. We right-clicked on the page and selected Inspect to open the DevTools
console.
3. In the console, selected the h2 elements using the querySelector method
using the tag name, and then the class:

document.querySelector('h2');

document.querySelector('.highlight-spanned');

In both cases we returned the same element!

Note: As we discussed earlier, the MDN UI has been updated and no longer uses
the highlight-spanned class. If you want to try this on your own (and I would
encourage you to do so!), try using the document-toc-heading class instead:

document.querySelector('h2');
document.querySelector('.document-toc-heading');

Two ways to select an h2 element with document.querySelector()

⚠️ .querySelector() Returns A Single Element ⚠️


I want to point out one potentially tricky thing - the .querySelector() method only
returns one element. This makes sense if you use it to search for an element by ID.
However, even
though .getElementsByClassName() and .getElementsByTagName() both
return a list of multiple elements, using .querySelector() with a class selector or a tag
selector will still only return the first item it finds.

querySelectorAll
LessonDownloads

The querySelectorAll Method


The .querySelector() method returns only one element from the DOM (if it exists).
However, there are definitely times when you will want to get a list of all elements with a
certain class or all of one type of element (e.g. all <tr> tags). We can use
the .querySelectorAll() method to do this!

// find and return a list of elements with the class


"header"

document.querySelectorAll('.header');

// find and return a list of <header> elements

document.querySelectorAll('header');

Here's the .querySelectorAll() method on MDN: Document.querySelectorAll()

Demo Recap
In this demo:

1. First, we navigated to the MDN Document.querySelectorAll()(opens in a new


tab) page.
2. We right-clicked on the page and selected Inspect to open the DevTools
console.
3. In the console, selected the h2 elements using the querySelectorAll method
using the tag name, and then the class:

document.querySelectorAll('h2');

4. We stored the output in a variable named listOfElements .

const listOfElements = document.querySelectorAll('h2');

5. We created a loop to iterate through the NodeList:

for (let i = 0; i < listOfElements.length; i++){

console.log('i is ' + i );

console.log(listOfElements[i]);

It's important to remember that .querySelectorAll() returns a NodeList -- not


an array so listOfElements won't have access to the array methods we are
used to. But NodeList has its own methods. You can see them on the
MDN NodeList(opens in a new tab) page.

Recap: querySelector and querySelectorAll


LessonDownloads

Recap
In this section, we took a brief look the history of browser support for standard DOM
methods, the rise of the jQuery library, and how jQuery's success brought about new
DOM methods. The new DOM methods we looked at are

 .querySelector() - returns a single element


 .querySelectorAll() - returns a list of elements
// find and return the element with an ID of "header"

document.querySelector('#header');

// find and return a list of elements with the class "header"

document.querySelectorAll('.header');

We also took a brief look that the list returned by .querySelectorAll() is a NodeList.
We saw that it is possible to loop over a NodeList with either its .forEach() method, or
the humble for loop:

const allHeaders = document.querySelectorAll('header');

for(let i = 0; i < allHeaders.length; i++){


console.dir(allHeaders[i]);
}

Further Research
 .querySelector() method on MDN(opens in a new tab)
 .querySelectorAll() method on MDN(opens in a new tab)
 NodeList on MDN

You've Learned A Lot!!!


In this lesson, we learned all about the DOM (Document Object Model).

We started by learning what the DOM is and how it gets created.

Then we discovered several JavaScript methods for programmatically


accessing DOM elements:

 .getElementById()
 .getElementsByClassName()

 .getElementsByTagName()
 .querySelector()

 .querySelectorAll()

Along the way we talked about the web interfaces that facilitate this access,
including:

 Element
 Node

Up next, we'll learn new DOM methods that allow us to alter and control page
content!

What You Will Learn


This is the lesson where we start to control the DOM with Javascript! By the
end of this lesson you will be able to:

 Use Javascript and DOM methods to create, delete, and manipulate DOM
elements.
 Understand the real power of combining JavaScript and the DOM.

I can't wait to share all of this with you!

Before We Get Started...


To be successful in this section, there are a couple of things from the previous
section that you need to know. You need to have a solid grasp of selecting
DOM elements using:

 document.getElementById()
 document.querySelector()

Also, remember the Node Interface and the Element interface we went over in
the previous section? Understanding how an interface determines the
properties and methods for an element and understanding how to research an
interface's properties and methods will be vital in this lesson.

If you get stuck, just jump back to the previous section that's giving you a bit of
trouble.

Our Practice Environment


LessonDownloads

Website Replica
Throughout this lesson, you'll learn skills and techniques to access and modify page
content. There's no better way to demonstrate these skills than through trying them out
on a real website! So I've created a replica of an older version of the Udacity homepage.

[OPTION 1] Using Your Local Code Editor


To work on the replica locally you'll need a code editor installed on your machine. You
can use Visual Studio Code(opens in a new tab) or any other modern code editor.

We have the code stored in a GitHub repository: https://github.com/udacity/course-


JS-and-the-DOM(opens in a new tab) . You can access this code either by cloning it
on your local machine.

In a terminal, navigate to the folder where you want to store the code. Then use git
clone :

git clone https://github.com/udacity/course-JS-and-the-


DOM

Alternatively, you can fork the repository to create an identical copy of the repository in
your own GitHub account and then clone the forked repository:

git clone https://github.com/<your-github-


username>/course-JS-and-the-DOM
A snapshot of Udacity's project repository

Accessing the Replica


Show TranscriptSummarize Video

To load the website, drag the index.html file into your browser.
In your code editor, look for the app.js file. That is where you'll be doing all of your work
in this lesson.

[OPTION 2] Using the Workspace


Coding locally works, but many students find it easier to use the workspace on the next
page for the exercises and demos in this course.

The process is very similar to coding locally, but there are a few minor differences.

More Files!
In your workspace you'll see some files and a folder that are not included the course
GitHub repository.

 package.json
 package-lock.json

 node_modules

Don't worry -- you don't need to touch these files. They are used to setup and run the
Node server that hosts the web page in a separate browser tab.

Loading the Web Page


To get the page running you'll need to start the Node server by typing an npm command
in the terminal:

npm run start

To see the web page, you'll need to click the OPEN THE WEB PAGE button at the
bottom of the screen.

That will open a new browser tab that contains the replica web page. The page will
update as you make changes.
Starting the server and opening the web page

Tips for Using the Workspace


1. Open the workspace in a new tab and keep it open while you work your way
through the course. You'll want to go back and forth between the workspace
and the classroom.
2. Expand the workspace to full screen. That will give you more room to work.
3. If the type in the workspace is too small, use your browser's zoom control to
magnify the screen.
Expand the workspace to full page

Getting and Setting HTML Content


In this section, we'll learn about three ways to get and set HTML content:

 innerHTML
 textContent

 innerText

By the end of this section, you'll know how to alter the HTML and text content of any
element on any website!
Let's jump right into it.

Open the Demo Project


If you are coding locally, you can just drag the index.html file into your browser.

If you are using the workspace, you'll need to run npm run start in the terminal and
click on the VIEW THE WEB PAGE button in the lower right corner of the workspace.

Remember, if you are using the workspace it is recommended that you keep the
workspace open in a separate tab of your browser because we'll be going back to it
regularly throughout this lessson.
There's only one HTML file -- index.html -- so this is what it should look like after you
open it:
There's only one HTML file -- index.html -- so this is what it should look like after you
open it:
The index page of the Udacity website loaded in a browser.

index.html

The `index.html` serves as a starter template for you to get started. There
might be a slight mismatch between the actual content of `index.html` file
downloaded from GitHub vs. the one shown in the demo. However, the
mismatch will not block you from practicing the classroom instructions.

Review: Selecting an Element


There are a few different ways to do this. Use your favorite method.

Write the DOM code necessary to select the first element with class: card

Submit

Let's store the first .card element in a variable for easy access:

const nanodegreeCard = document.querySelector('.card');

Now that we've stored the first card element in the nanodegreeCard variable, we can
use nanodegreeCard to refer to this element instead of having to
use document.querySelector('.card') to select the element every time we need access to
it.

innerHTML
LessonDownloads
An Element's Inner HTML
Every element inherits properties and methods from the Element Interface (remember
this from the previous lesson!). This means that every element has
an .innerHTML property. This property, as it's rightly named, represents the markup of
the element's content. We can use this property to:

 get an element's (and all of its descendants!) HTML content


 set an element's HTML content

Show TranscriptSummarize Video

Demo Recap
In this demo, we:

1. Opened the replica home page either in our local coding environment or in the
Workspace.
2. Opened the console.
3. Selected the first element with the card class and saved it in a variable
named card :

const card = document.querySelector('.card');

4. Accessed the innerHTML of the saved element:

card.innerHTML;

We saw card.innerHTML contains all of the HTML content of the selected element!

Awesome! Now let's check your understanding of .innerHTML .

Question 1 of 2
What is .innerHTML ?
a property

a method

an element

an interface
Submit

Question 2 of 2
What does .innerHTML return?

a DOM element
a Node

a string

an array

an object
Submit

💡 Innie vs Outie 💡
The .innerHTML property sets or returns the HTML content inside the selected
element (i.e. between the tags).

There's also the rarely used .outerHTML property. .outerHTML represents the
HTML element itself, as well as its children.

<h1 id="pick-me">Greetings To <span>All</span>!</h1>


const innerResults = document.querySelector('#pick-
me').innerHTML;
console.log(innerResults); // logs the string: "Greetings
To <span>All</span>!"

const outerResults = document.querySelector('#pick-


me').outerHTML;
console.log(outerResults); // logs the string: "<h1
id="pick-me">Greetings To <span>All</span>!</h1>"

textContent and innerText


LessonDownloads

An Element's Text Content


So .innerHTML will get/set an element's HTML content. If we just want the text
content, we can use the fantastically named .textContent property!

The .textContent property will:

 set the text content of an element and all its descendants


 return the text content of an element and all its descendants

Let's check it out!


Show TranscriptSummarize Video

Demo Recap
In this demo, we:

1. Selected the first element with the card class and saved it in a variable
named card :

const card = document.querySelector('.card');

1. Accessed the textContent of the saved element:


card.textContent;

1. Accessed the innerHTML of the saved element to compare the two:

card.innerHTML

We discovered that the innerHTML property contains all of the HTML for the element
while textContent only contains the element's text.
Check out the .textContent 's documentation page on MDN: textContent
docs(opens in a new tab)

Setting an Element's Text Content


Setting an element's text content is easy, just set it like you would any other property:

nanodegreeCard.textContent = "I will be the updated text


for the nanodegreeCard element!";
Show TranscriptSummarize Video

Demo Recap
In this demo, we:

1. Selected the first element with the card class and saved it in a variable
named card :

const card = document.querySelector('.card');

1. Accessed the textContent of the saved element:

card.textContent;

1. Set the textContent to a new value:

card.textContent = "I will be the updated text for the


card element!";
1. We reviewed the text on the page and confirmed that the updated text also
appears in the Elements pane.

Check Your intuition About textContent

Quiz Question
<h1 id="test">Ice Cream Flavors</h1>

Given the HTML above, what will be the .textContent value after running this
code:

const myElement = document.querySelector('#test');


myElement.textContent = 'The <strong>Greatest</strong>
Ice Cream Flavors';

Ice Cream Flavors

The Greatest Ice Cream Flavors

The <strong>Greatest</strong> Ice Cream Flavors


running this code will cause an error
Submit

We just saw that passing text that contains HTML characters to .textContent will not
display the content as HTML. Instead, it will still display everything as text - even the
HTML characters!

If you'd like to update an element, including its HTML, then you need to use
the .innerHTML property:

// doesn't work as expected


myElement.textContent = 'The <strong>Greatest</strong>
Ice Cream Flavors';

// works as expected
myElement.innerHTML = 'The <strong>Greatest</strong> Ice
Cream Flavors';
Show TranscriptSummarize Video

Demo Recap
In this demo, we:

1. Selected the "Our Amazing Community" header by right-clicking on it and


selecting Inspect.
2. Bumped up the font-size by editing the font-size property of the element in
the Styles pane:
element.style {

font-size: 1.5em;

4. Updated the text of the element:

const heading = $0;

heading;
5. Accessed the textContent of the saved element:

heading.textContent = "Our Amazing Community


<em>ROCKS</em>!"

6. Oops! The <em></em> tags are rendered as text, not HTML. We fixed that
by using the innerHTML property instead:

heading.innerHTML = "Our Amazing Community


<em>ROCKS</em>!"

By using innerHTML instead of textContent the string now shows up as rendered


HTML!

An Element's Text Content - Version 2!


We can't close this section out without looking at the .innerText property!

Like the .textContent property, the .innerText property can be used to get/set an
element's text content, but there are some important differences between the two
properties.

.textContent sets/gets the text content of an element...pretty clear and simple.

.innerText , on the other hand, is a little trickier. Let's see this in action and then we'll
discuss it!
Show TranscriptSummarize Video

Demo Recap
In this demo, we:

1. Selected the first element with the card class and saved it in a variable
named card :
const card = document.querySelector('.card');

2. Selected the "Enroll Now" text on the card and hid it using CSS in
the Styles pane:

element.style {

display: none;

3. Accessed the textContent of the saved element -- it shows all of the text in
the element!:

card.textContent;

4. Accessed the innerText of the saved element:

card.innerText;

When we access the text content with innerText , the hidden text ("Enroll Now") does
not appear and the "New" text appears in all uppercase letters. .innerText returns
the visible text of the element.
This is an important distinction! If CSS is used to hide any text inside that
element, .innerText will not return that text, while .textContent will return it. And it's
not just the hiding/showing nature of CSS that .innerText adheres
to, .innerText will also honor changes to things like capitalization.

The .textContent property has been a standard for quite a long time.
Conversely, .innerText property is a relatively new addition to the HTML specification.
It has been around for a while but was not fully supported by all browsers because it
was not a part of the HTML specification.

Between .textContent and .innerText , you probably want to


use .textContent since that will return all of the text no matter what. Rarely will you
actually want only the visible text.
Exercise: Update Program Title
LessonDownloads

Update the Program Title


Udacity is considering changine the name of the Data Foundations Nanodegree and
wants to know how the new name will look on the Udacity home page. Your assignment
is to use your content update skills and to change the program name on the replica
home page.

I like the name "Everything You Need to Know About Data" -- but you might have a
better idea.

Just make sure that you:

1. Select the correct element


2. Update the HTML correctly

When you are done, the page should look something like this:
Updated home page with updated title
Solution: Update Program Title
LessonDownloads

My Solution
Here's how I tackled this exercise:

1. I right-clicked on the "Data Foundations" text and clicked Inspect.


2. In the Elements pane, I clicked on the element that contains the "Data
Foundations" text.
3. I used the $0 to save the element in a variable I called programName .

const programName = $0;

4. I used the innerHTML property to update the HTML:

programName.innerHTML = "<em>Everything</em> You Need to


Know About Data";
Updated home page with updated title
I used innerHTML because I wanted to render Everything in italics. If I didn't want the
fancy styling, I could have used innerText or textContent :

programName.innerText = "Some Things You Need to Know


About Data";

Updated home page with updated title using innerText


Or you could use textContent :

programName.textContent = "A Few Things You Need to Know


About Data";

Updated home page with updated title using textContent

Recap: Update Existing Content


LessonDownloads

Update Existing Content Recap


In this section, we looked at multiple ways to change page content:

 .innerHTML
 .textContent

 .innerText

We saw that to set HTML content for an element, out of the three properties list above,
we can only use .innerHTML . Using .textContent will erroneously include the
HTML characters as plain text inside the element.

We also looked at the difference


between .textContent and .innerText . .textContent completely ignores any CSS
styling and returns all of the element's HTML just as it's listed in the HTML. On the other
hand, the .innerText property will take CSS styling into consideration and will return
the text that is visibly rendered on the page.
What You Will Learn
In this section we will create new content and add it to the page using three
methods:

 .createElement()
 .creatextNode()
 .appendChild()
 .insertAdjacentHTML()

Are you ready to create some new content? Let's get started!

Learning About createElement

As a developer, there is always something new to learn so it's important to be


comfortable with to do some of your own research on this one.

Go to MDN Web Docs(opens in a new tab) and find the documentation


for createElement .

Question 1 of 2
You've learned about the Document object, the Node Interface, and the Element
interface. Where does .createElement() come from?

the Element interface

the Document object


the Node interface

from another source we haven't seen yet


Submit

What is the URL for the "createElement" page on MDN?

Submit

Now that you have found the documentation, take a minute to read through it to help
you answer the question below.

Question 2 of 2
Which of the following would create a new paragraph element?

document.createElement(p);

element.createElement('p');
document.createElement('p');

document.createElement('paragraph');
Submit

As you've already discovered, the .createElement() method is a method on


the document object:

// creates and returns a <span> element

document.createElement('span');

// creates and returns an <h3> element

document.createElement('h3');

Here's the .createElement() documentation page on MDN: createElement


docs(opens in a new tab)

Using createElement to Create a New Content


Element
Show TranscriptSummarize Video

Demo Recap
In this demo, we:

1. Used createElement to create a new <span> element and saved it in a


variable named container :

const container = document.createElement('span');

1. Used textContent to add some text to the new element we created:

container.textContent = ", right now!";

1. Viewed container to confirm that our text was added:

container

Next we'll learn how to add the new element to the page!

Adding Content To The Page


You may have noticed that using document.createElement() to create an element
didn't actually add that newly created element anywhere on the page! Creating an
element...just creates it. It doesn't add it to the DOM. Since the element isn't added to
the DOM, it doesn't appear in the page (if you remember, the DOM is the parsed
representation of the page). So, now that we can create brand new elements, we need
to be able to add them to the DOM so that they'll show up on the page.

We can use the .appendChild() method to add an element to the page! Before we
see how this element works, let's quickly define the word "append". There are several
different definitions of the word, but I like the wording of the Cambridge Dictionary's the
best:

to add something to the end of a piece of writing


definition of the word "append" (source(opens in a new tab) )
Now, to use the .appendChild() method, it needs to be called on another element,
not the document object!

// create a brand new <span> element


const newSpan = document.createElement('span');

// select the first (main) heading of the page

const mainHeading = document.querySelector('h1');

// add the <span> element as the last child element of


the main heading

mainHeading.appendChild(newSpan);

I like the Cambridge Dictionary's version because it clearly states how the content is
added at the end. The .appendChild() method is called on one element, and is
passed the element to append. The element that is about to be appended is added as
the last child. So, in the example above, the <span> element will appear in the DOM
as a child of the <h1> ...but it will appear at the end, after all text and any other
elements that might be in the <h1> .

Here's the .appendChild() documentation page on MDN: appendChild(opens in a


new tab)

⚠️ .appendChild() Needs An Element! ⚠️


This is stated above, but I wanted to call this out, specifically. When you're using
the .appendChild() method, it must be called on an existing element. To be clear,
you can't call this on the document object, so the following will result in an error:

const newSpan = document.createElement('span');

// causes an error
document.appendChild(newSpan);
Show TranscriptSummarize Video
Demo Recap
In this demo, we:

1. Used createElement to create a new <span> element and saved it in a


variable named container :

const newSpanElement = document.createElement('span');

1. Used textContent to add some text to the new element we created:

newSpanElement.textContent = ', right now!';

1. Selected the heading we want to append our text to:

const mainheading = document.querySelector('h1');

1. Used appendChild to append our text the selected element:

mainheading.appendChild(newSpanElement);

Now we can see the new text on the page!!!

Creating Text Nodes with .createTextNode()

Just like you created new elements with the .createElement() method, you can also
create new text nodes using the .createTextNode() method. Take a look at the following
code that:

 creates a paragraph element


 creates a text node
 appends the text node to the paragraph
 appends the paragraph to the tag

const myPara = document.createElement('p');

const textOfParagraph = document.createTextNode('I am the text for the


paragraph!');
myPara.appendChild(textOfParagraph);

document.body.appendChild(myPara);

However, since you already know about the .textContent property, the code below will
provide the exact same result:

const myPara = document.createElement('p');

myPara.textContent = 'I am the text for the paragraph!';

document.body.appendChild(myPara);

Therefore, instead of creating a new text node and appending it to an element, it's faster
and easier to just update the element's text with the .textContent property.

For more info, check out the documentation: createTextNode() docs(opens in a new
tab)

Quiz Question
What happens after running this code?

const mainHeading = document.querySelector('h1');

const otherHeading = document.querySelector('h4');

const excitedText = document.createElement('span');

excitedText.textContent = '!!!';

mainHeading.appendChild(excitedText);

otherHeading.appendChild(excitedText);

Other Ways to Insert HTML


LessonDownloads
Inserting HTML In Other Locations
By definition, the .appendChild() method will add an element as the last child of the
parent element. It's impossible to put it as the first child or anywhere else...it has to be
the last child. Wouldn't it be nice if there were a little flexibility in where we could add the
child element?

Enter the .insertAdjacentHTML() method! The .insertAdjacentHTML() method


has to be called with two arguments:

 the location of the HTML


 the HTML text that is going to be inserted

The first argument to this method will let us insert the new HTML in one of four different
locations

 beforebegin – inserts the HTML text as a previous sibling


 afterbegin – inserts the HTML text as the first child

 beforeend – inserts the HTML text as the last child

 afterend – inserts the HTML text as a following sibling

Let's check out the insertAdjacentHTML(opens in a new tab) documentation page on


MDN:
Show TranscriptSummarize Video

At 0:22 seconds, the instructor says "... this has to be text, not HTML. If you pass
HTML, then that HTML will actually be displayed". There is a correction:

The second argument text of insertAdjacentHTML() method parses the


specified text as HTML and inserts the resulting nodes into the DOM tree at a specified
position.
A visual example works best, and MDN's documentation has a fantastic example that I'll
modify slightly:

<!-- beforebegin -->

<p>
<!-- afterbegin -->

Existing text/HTML content

<!-- beforeend -->

</p>

<!-- afterend -->

Here's how we'd call .insertAdjacentHTML() :

const mainHeading = document.querySelector('#main-


heading');
const htmlTextToAdd = '<h2>Skydiving is fun!</h2>';

mainHeading.insertAdjacentHTML('afterend',
htmlTextToAdd);

Add Page Content


LessonDownloads

Add Your Advice to Future Students in the


Community Section
Members of Udacity community often help each other. What advice would you give to a
new student? Let's add your advice in a new element in the Community section of the
home page.

1. Find the Community section. Hint: the class name for that section
is testimonials .
2. Create a new h2 element with the text Advice for New Udacity Students and
use appendChild to insert your new element at the end of the Community
section.
3. Use insertAdjacentHTML to add a p element with one or two sentences of
advice after the h2 element you created.
When you are done, the page should look something like this:

Updated Community section with new Advice elements


Note that the styling here doesn't look as nice as the rest of the page. We'll learn how to
use JavaScript to add or update styles in the next part of the lesson!

My Solution
Here's how I tackled this exercise:

Step 1: Find the element to update


1. I right-clicked in the section with the "Our Amazing Community" text and
clicked Inspect.
2. In the Elements pane, I clicked on the element that has the testimonials class.
3. I used the $0 to save the element in a variable I called programName .

// create variable to store the location on the page

const community = $0;

Alternatively, I could have used .querySelector() , like this:

// create variable to store the location on the page

const community =
document.querySelector('.testimonials');

Step 2: Add the header element to the page


1. I used createElement to create an h2 element:

// create element

const adviceHeader = document.createElement('h2');

2. I used .textContent to set the text of the new element:

// add text to new element

adviceHeader.textContent = 'Advice for New Udacity


Students';

3. I used .appendChild() to add the header element to the page:

// append element to the page

community.appendChild(adviceHeader);

Alternatively, I could have added text to the new element


using .createTextNode() like this:

// create element

const adviceHeader = document.createElement('h2');


// create text node

const headerText = document.createTextNode('Advice for


New Udacity Students');

// append text node to new element

adviceHeader.appendChild(headerText);

// append element to the page

community.appendChild(adviceHeader);

Step 3: Add advice paragraph


1. I created an HTML string with advice in a <p> element:

// create HTML string

const adviceString = '<p>Set aside specific blocks of


time each week \

for your coursework. Add those blocks to


your calendar and \

set reminders.</p>';

2. I used insertAdjacentHTML to add the paragraph after the header element


using afterend :

// insert the HTML string after the header element

adviceHeader.insertAdjacentHTML('afterend',
adviceString);
Alternatively, I could have used insertAdjacentHTML with beforeend on
the community element:

// create HTML string


const adviceString = '<p>Set aside specific blocks of
time each week \
for your coursework. Add those blocks to
your calendar and \
set reminders.</p>';

// insert the HTML string before the end of the community


element
community.insertAdjacentHTML('beforeend', adviceString);

Add New Page Content Recap


In this section, we learned how to create new DOM elements and add them to the page.
We looked at the following methods:

 .createElement() to create new elements


 .appendChild() to add a child element to a parent element as its last child

 .createTextNode() to create a text node

 .insertAdjacentHTML() to put HTML text anywhere around an element

Some important things to note are:

 if an element already exists in the DOM and this element is passed


to .appendChild() , the .appendChild() method will move it rather than
duplicating it
 an element's .textContent property is used more often than creating a text
node with the .createTextNode() method
 the .insertAdjacentHTML() method's second argument has to be text, you
can't pass an element
Further Research
 createElement on MDN(opens in a new tab)
 createTextNode on MDN(opens in a new tab)
 appendChild on MDN(opens in a new tab)
 insertAdjacentHTML on MDN

What's Next? Removing Content!


In this quick section, you're going to learn how to remove content from the page.
Specifically, we'll look at these new methods:

 .removeChild()
 .remove()

In the process, you'll also learn about these two properties:

 .firstElementChild
 .parentElement

Removing a Child Element


We can use the .removeChild() method to...wait for it...remove a child element.
Basically, this is exactly the opposite of the .appendChild() method. So just like
the .appendChild() method, the .removeChild() method requires:

 a parent element
 the child element that will be removed

<parent-element>.removeChild(<child-to-remove>);

Here's the .removeChild() documentation page on MDN: removeChild docs(opens


in a new tab)
Let's see how to use this method:
Show TranscriptSummarize Video

Demo Recap
In this demo:

1. We found the hero_module div in the Elements pane and used $0 to store
the value of that element in a variable called cardContainer :

const cardContainer = $0;

1. We checked the firstChild property of cardContainer and discovered that it


contained text -- not the div we were expecting:

cardContainer.firstChild;

1. So instead we accessed the firstElementChild , which gives us the first child


that is an element:

cardContainer.firstElementChild;

1. We stored the value of firstElementChild in a variable called firstCard :

const firstCard = cardContainer.firstElementChild;

1. And used removeChild to remove it from its parent:

cardContainer.removeChild(firstCard);

And now the first card is gone from the page and the DOM!!!

A drawback (and workaround!) with


the .removeChild() Method
Just like the .appendChild() method, there's a (somewhat minor) drawback to
the .removeChild() method. Both methods require access to the parent to
function.

However, we don't actually need to have the parent element because there is a
workaround! Just like the .firstElementChild property can be called on a parent
element to access its first element, every element also has a parentElement property
that refers to its parent! So if we have access to the child element that we're about to
add or remove, you can use the parentElement property to "move focus" to the
element's parent. Then we can call .removeChild() (or .appendChild() ) on that
referenced parent element.

Let's look at an example:

const mainHeading = document.querySelector('h1');

mainHeading.parentElement.removeChild(mainHeading);

Let's walk through this code.

const mainHeading = document.querySelector('h1');

The preceding code will select the first <h1> on the page and stores it in
the mainHeading variable. Now to the next line:

mainHeading.parentElement.removeChild(mainHeading);

This starts with the mainHeading variable. It calls .parentElement , so the focus of
the next code is directed at the parent element. Then .removeChild() is called on the
parent element. Finally, mainHeading itself is passed as the element that needs to
be removed from its parent.

So an element uses itself to remove itself from its parent. Pretty cool, huh?
Removing a Child Element (Part 2!)
We went through all of those steps selecting an element, using DOM traversal
techniques like .parentElement and .firstElementChild , so that we can remove a
child element. I showed you this way so that you can get some exposure and practice to
moving around in the DOM.

Now, you might be glad (or frustrated! haha) to find out there's an easier way to do all
this! We can remove the child element directly with the .remove() method:

const mainHeading = document.querySelector('h1');

mainHeading.remove();

Here's the .remove() documentation page on MDN: .remove() docs(opens in a new


tab)

Remove Page Content Recap


In this short section, we learned two ways to remove an element from the page. You
learned about:

 .removeChild()
 .remove()

The difference is that with .removeChild() must be called on the parent of the
element being removed and must be passed the child to be removed,
while .remove() can be called directly on the element to delete.

We also learned about the following helpful properties:

 .firstChild
 .firstElementChild

 .parentElement
The difference between .firstChild and .firstElementChild , is
that .firstElementChild will always return the first element,
while .firstChild might return whitespace (if there is any) to preserve the formatting of
the underlying HTML source code.

Further Research
 removeChild on MDN(opens in a new tab)
 remove on MDN(opens in a new tab)
 firstChild on MDN(opens in a new tab)
 firstElementChild on MDN(opens in a new tab)
 parentElement on MDN

In this section, we'll be looking at controlling page and element styling using the following
properties and methods:

 .style.<prop>
 .cssText
 .setAttribute()
 .className
 .classList

Before we get started, let's take a quick review of CSS specificity. This will come in handy as we
work on styling page content with JavaScript.

Quiz Question
Before we begin, put these in the correct order of CSS specificity. Put the least-
specific option at the top and the most-specific option at the bottom.
rules in a stylesheet
rules in a tag's style attribute
rules in a <style> tag
CSS Specificity
To be successful in this section, it will help to have an understanding of how
CSS Specificity works. According to the MDN, "specificity" is:

the means by which browsers decide which CSS property values are the most relevant
to an element and, therefore, will be applied.
Basically, the closer the style rule is to an element, the more specific it is. For
example, a rule in a style attribute on an element will override a style rule for
that element in a CSS stylesheet. There is also the specificity of the type of
selector being used. An ID is more specific than a class.

If you'd like to learn more about CSS Specificity, check out the MDN
documentation: CSS Specificity

Modify Using the style Property


LessonDownloads

Modifying an Element's Style Attribute


Let's jump back to your knowledge of CSS. When trying to style an element, the most-
specific rules that you can write for an element are written in that
element's style attribute. Lucky for us, we can access an element's style attribute
using the .style property!

const mainHeading = document.querySelector('h1');

mainHeading.style.color = 'red';

Now, I want to point out that when using the .style property, you can only
modify one CSS style at a time. That's why the previous code has .style.color =
'red' and not just .style = 'red' .

Check out the MDN documentation page for more


information: HTMLElement.style(opens in a new tab)
Show TranscriptSummarize Video
Demo Recap
In this demo, we:

1. Found "Our Amazing Community" header in the DOM and used $0 to store
the value of that element in a variable called heading :

const heading = $0;

1. Set the color to orange using the element's style property:

heading.style.color = 'orange';

1. Reviewed the element's style in the Styles tab.


2. Bumped up the font size to 2em:

heading.style.fontSize = '2em';

1. Reviewed the element's style property, which returned


a CSSStyleDeclaration .

heading.style;

1. We scrolled through the style declaration to review the style attributes of the
element. We saw the two styles we added and then looked at
the cssText property, which consists of the two items we added: color:
orange; font-size:2em';

We'll learn more about cssText below.

Adding Multiple Styles At Once


We've seen how the .style.<property> syntax will let us change just one piece of
styling for an element. So if we wanted to set an element's color, background color, and
font size, we'd have to use three separate lines of code:

const mainHeading = document.querySelector('h1');


mainHeading.style.color = 'blue';

mainHeading.style.backgroundColor = 'orange';

mainHeading.style.fontSize = '3.5em';

...and that's just for setting three styles. Imagine if we needed 15 or 20 different styles!
So the .style.property syntax is perfect for setting one style at a time, but it's not
great for controlling multiple styles.

Fortunately, we can use the .style.cssText property to set multiple CSS styles at
once!

const mainHeading = document.querySelector('h1');

mainHeading.style.cssText = 'color: blue; background-color: orange; font-


size: 3.5em';

Notice that when using the .style.cssText property, you write the CSS styles just as
you would in a stylesheet; so you write font-size rather than fontSize . This is
different than using the individual .style.<property> way.

Quiz Question
<p id="quizzing-quizzes" style="color: orange;">Howdy</p>

Which of the following styles will change in the `#quizzing-quizzes" element after
running this code?

const quiz = document.querySelector('#quizzing-quizzes');


quiz.style.cssText = 'width: 30px; textDecoration: underline;'
Setting An Element's Attributes
Another way to set styles for an element is to bypass
the .style.<property> and .style.cssText properties altogether and use
the .setAttribute() method:

const mainHeading = document.querySelector('h1');

mainHeading.setAttribute('style', 'color: blue;


background-color: orange; font-size: 3.5em;');

Check out the MDN documentation for more information: Element.setAttribute()


(opens in a new tab)

.setAttribute() Is Not Just For Styling


The setAttribute() method is not just for styling page elements. You can use this
method to set any attribute for an element. If you want to give an element an ID, you
can do that!:

const mainHeading = document.querySelector('h1');

// add an ID to the heading's sibling element

mainHeading.nextElementSibling.setAttribute('id',
'heading-sibling');

// use the newly added ID to access that element

document.querySelector('#heading-
sibling').style.backgroundColor = 'red';

The last two lines could've been combined into one to bypass setting an ID and just
styling the element directly:
mainHeading.nextElementSibling.style.backgroundColor =
'red';

...but this was just to demonstrate that it's possible to set an attribute with JavaScript
that affects the DOM which then can be used immediately

Quiz Question
If you have this HTML element:

<h2 id="item-name">Chocolate Cupcake</h2>

<p id="description">Chocolate cake, fudge filling and


vanilla icing</p>

Which of these set the background color the description brown and the text to
white?

Hint: look at the code carefully. In some of the options there are tiny syntax
errors that will prevent the code from running the way you might expect.

const desc = document.querySelector('#description');


desc.setAttribute('style', 'color: "white"; background:
"brown"');

const desc = document.querySelector('#description');


desc.style.cssText = 'color: white';
desc.style.cssText = 'background: brown';
const desc = document.querySelector('#description');
desc.setAttribute('style', 'color: white; background: brown');

const desc = document.querySelector('#description');


desc.setAttribute('style', 'color: white');
desc.setAttribute('style', 'background: brown');

const desc = document.querySelector('#description');


desc.setAttribute('style', 'color: white, background: brown');

const desc = document.querySelector('#description');


desc.style.color = "white";
desc.style.backgroundColor = "brown";

const desc = document.querySelector('#description');


desc.style.cssText = 'color: white; background: brown';
Submit

💡 Why background and not background-color ?

Did you notice that I used background in the quiz above? That's
because background is a shorthand property that sets all of the background styles in
one statement, including the background color. You can read about it in the MDN
documentation: CSS - background(opens in a new tab) .

Problem: Separation of Concerns is a Best Practice


The web industry favors separation of concerns:

 HTML should be in the HTML file


 Styling should be in a CSS file
 Interactivity should be in a JavaScript file

We violate that when we set styles using JavaScript. But to make our website
interactive, we often need to change the style of an element.

Solution: Add/Remove Classes


We keep all of the styles in our CSS file and use our JavaScript code to control the
class attribute for an element. This allows us to change the styling by adding or
removing a class.

Accessing an Element's Classes Using .className

The .className property returns a string of all of the element's classes. If an element
has the following HTML:

<h1 id="main-heading" class="ank-student jpk-modal">Learn Web


Development at Udacity</h1>

We could use .className to access the list of classes:

const mainHeading = document.querySelector('#main-heading');

// store the list of classes in a variable

const listOfClasses = mainHeading.className;


// logs out the string "ank-student jpk-modal"

console.log(listOfClasses);

The .className property returns a space-separated string of the classes.

Setting An Element's Class


.className is a property, so we can set its value just by assigning a string to the
property:

mainHeading.className = 'im-the-new-class';

The above code erases any classes that were originally in the
element's class attribute and replaces it with the single class im-the-new-class .

Adding or Removing Classes Using String and Array


Methods
Since .className returns a string, it makes it hard to add or remove individual
classes. We can, however, convert this space-separated string into an array using the
JavaScript string method, .split() :

const arrayOfClasses = listOfClasses.split(' ');

// logs out the array of strings ["ank-student", "jpk-modal"]

console.log(arrayOfClasses);

Now that we have an array of classes, we can do any data-intensive calculations:

 use a for loop to loop through the list of class names


 use .push() to add an item to the list
 use .splice() to remove an item from the list
 use .join() to convert the array back into a string

Let's replace the jpk-modal class with im-the-new-class :

// access the element

const mainHeading = document.querySelector('#main-heading');

// store the list of classes in a variable

const arrayOfClasses = mainHeading.className.split(' ');

// loop through the array and remove the jpk-modal-class

for (let i = 0; i < arrayOfClasses.length; i++ ) {

if (arrayOfClasses[i] === 'jpk-modal') {

arrayOfClasses.splice(i, 1);

// add new class to the array

arrayOfClasses.push('im-the-new-class');

// convert the array to a space-separated string

const newClassList = arrayOfClasses.join(' ');

// use className to set the list of classes for the element

mainHeading.className = newClassList;
That works -- but it is a lot of work! On the next page we'll explore an easier way to add
and remove classes from an element.

Use classList to Access an Element's Class


LessonDownloads

The .classList Property


The .classList property is newer than the .className property, but is much nicer,
check it out:

<h1 id="main-heading" class="ank-student jpk-modal">Learn Web


Development at Udacity</h1>

const mainHeading = document.querySelector('#main-heading');

// store the list of classes in a variable

const listOfClasses = mainHeading.classList;

// logs out ["ank-student", "jpk-modal"]

console.log(listOfClasses);

Demo Recap
In this demo, we:

1. Found "Our Amazing Community" header in the DOM and used $0 to store
the value of that element in a variable called heading:

const heading = $0;

1. Checked the elements classList property to see if it contains the text-


center class:
heading.classList.contains('text-center');

1. Added the ice-cream class to the heading element using add:

heading.classList.add('ice-cream');

1. Removed the ice-cream class from the heading element using remove:

heading.classList.remove('ice-cream');

1. Removed the text-centerclass using toggle:

heading.classList.toggle('text-center');

1. Added the text-centerclass back using toggle:

heading.classList.toggle('text-center');

This is so much easier than using className to add or remove classes!

Question 3 of 3
What happens if you try to toggle a nonexistent class? For example, if you had
this HTML:

<h1 id="main-heading" class="ank-student">Learn Web


Development at Udacity</h1>

...what would happen after running the following JavaScript:

const mainHeading = document.querySelector('#main-


heading');
mainHeading.classList.toggle('richard');

Style Page Content


LessonDownloads
Update the Home Page Colors
Udacity is considering an update to the colors on the home page. Your job is to use
your JavaScript page styling knowledge to mock up the new colors on the replica home
page two different ways:

Use the .style property to add new styles to an element


We aren't sure yet about the styling for the buttons on the page. We are considering
changing the color and shape of the Start Learning Now button. Use
the style property of the button with the id start-now to:

1. Change the button's background color to #2015ff .


2. Change the button's border radius to 5rem .

Use .classList Methods to add a new class


We're pretty sure about the styling changes for the page background and card elements
so we've already those styles in a new css file named new-styles.css that we have
linked in our HTML file. To change the page styling to use the new styles you need to:

1. Add the new-hero class to the section with the hero--homepage class.
2. Add the new-card class to all of the elements with the card class.

Hint to make this change to all of the elements with the card class you'll need to use a
loop.
When you are done, the page should look like this:

Solution: Style Page Content


LessonDownloads
My Solution

Step 1: Style the Start Learning Now button


I used .querySelector to select the button:

const start = document.querySelector('#start-now');

Then I used the button's style property to set the background color and border radius.

start.style.backgroundColor = '#2015ff';

start.style.borderRadius = '5rem';

Step 2: Style the hero section


I used .querySelector and the .add() method on the classList :

// select the hero element

const hero = document.querySelector('.hero--homepage');

// add the new class

hero.classList.add('new-hero');

Step 3: Style the card elements


I used .querySelectorAll to create a NodeList of all of the .card elements:

// select the card elements

const cardList = document.querySelectorAll('.card');

Then I looped through the list and added the new-card class to each element:

for (i = 0; i < cardList.length; i++) {


cardList[i].classList.add('new-card');

What do you think? Does the home page look better this way?

Style Page Content


LessonDownloads

Style Page Content Recap


We learned a ton of content in this section! We looked at:

 modifying individual styles with .style.<prop>


 updating multiple styles at once with .style.cssText
 getting/setting a list of classes with .className
 getting/setting/toggling CSS classes with .classList

My recommendation to you is that, out of the list of techniques you learned in this
section, to use the .classList property more than any other. .classList is by far the
most helpful property of the bunch, and it helps to keep your CSS styling out of your
JavaScript code.

Further Research
 style on MDN(opens in a new tab)
 Article: Using dynamic styling information(opens in a new tab)
 DOM methods to control styling(opens in a new tab)
 nextElementSibling on MDN(opens in a new tab)
 className on MDN(opens in a new tab)
 classList on MDN(opens in a new tab)
 Specificity on MDN

What You Learned


We covered a lot in this lesson! You now know how to:

 Update page content


 Add new content
 Remove content
 Style elements

Up next you'll learn how to write code to respond to user actions.

Running Code in Response to User Actions!


In the previous lesson, we did a lot of work adding, removing, and styling page
content in the browser's DevTools.

In this lesson, you'll learn how to run this DOM manipulating JavaScript code
in response to actions your users take.

Lesson Overview
To recap, we'll be looking at:

 Events - what they are


 Responding to an event - how to listen for an event and respond when one
happens
 Event Data - harness the data that is included with an event
 Stopping an event - preventing an event from triggering multiple responses
 Event Lifecycle - the lifecycle stages of an event
 DOM Readiness - events to know when the DOM itself is ready to be
interacted with
This lesson is chock full of incredibly useful information, so don't skim over
anything!

Website Replica
Throughout this lesson, you'll learn skills and techniques to access and modify page
content. There's no better way to demonstrate these skills than through trying them out
on a real website! So I've created a replica of an older version of the Udacity homepage.
Replica of an older version of the Udacity Home page
There are two ways for you to access the replica website:

 Using a code editor on your local machine


 Using the workspace on the next page

Either way you'll get the same coding experience so choose whichever is easiest for
you to work with.

[OPTION 1] Using Your Local Code Editor


To work on the replica locally you'll need a code editor installed on your machine. You
can use Visual Studio Code(opens in a new tab) or any other modern code editor.

We have the code stored in a GitHub repository: https://github.com/udacity/course-


JS-and-the-DOM(opens in a new tab) . You can access this code either by cloning it
on your local machine.

In a terminal, navigate to the folder where you want to store the code. Then use git
clone :

git clone https://github.com/udacity/course-JS-and-the-


DOM

Alternatively, you can fork the repository to create an identical copy of the repository in
your own GitHub account and then clone the forked repository:

git clone https://github.com/<your-github-


username>/course-JS-and-the-DOM
A snapshot of Udacity's project repository

Accessing the Replica


Show TranscriptSummarize Video

To load the website, drag the index.html file into your browser.

In your code editor, look for the app.js file. That is where you'll be doing all of your work
in this lesson.

[OPTION 2] Using the Workspace


Coding locally works, but many students find it easier to use the workspace on the next
page for the exercises and demos in this course.

The process is very similar to coding locally, but there are a few minor differences.

More Files!
In your workspace you'll see some files and a folder that are not included the course
GitHub repository.

 package.json
 package-lock.json

 node_modules

Don't worry -- you don't need to touch these files. They are used to setup and run the
Node server that hosts the web page in a separate browser tab.

Loading the Web Page


To get the page running you'll need to start the Node server by typing an npm command
in the terminal:
npm run start

To see the web page, you'll need to click the OPEN THE WEB PAGE button at the
bottom of the screen.

That will open a new browser tab that contains the replica web page. The page will
update as you make changes.

Starting the server and opening the web page

Tips for Using the Workspace


1. Open the workspace in a new tab and keep it open while you work your way
through the course. You'll want to go back and forth between the workspace
and the classroom.
2. Expand the workspace to full screen. That will give you more room to work.
3. If the type in the workspace is too small, use your browser's zoom control to
magnify the screen.

Expand the workspace to full page


An event is like an announcement. When something happens in the browser, the
browser will make an announcement. We can use Javascript to listen for the
announcement and respond.

Seeing An Event
There is a hidden world of events going on right now on this very page! It's really hard to
actually see into this hidden world, though. So how can we know that events
really are being announced? If they are being announced, how come they're not easy
for us to see?

Fortunately, the Chrome browser has a special monitorEvents() function that will let us
see different events as they are occurring.
Check out the documentation for the monitorEvents() function(opens in a new
tab) in the Console Utilities API reference page of the Chrome DevTools
documentation.

Demo Recap
We ran the monitorEvents to monitor the document object:

// start displaying all events on the document object

monitorEvents(document);

With the monitorEvents function running, executed several events in the


browser including:

 click
 dblclick
 scroll

However, there are hundreds more!

The monitorEvents function will keep spitting out all of the events that are
happening on the targeted element until the end of time...that, or until you
refresh the page. Alternatively, the Chrome browser does offer
an unmonitorEvents() function that will turn off the announcing of events for
the targeted element:

// turn off the displaying of all events on the document


object.

unmonitorEvents(document);

One last little bit of info on monitorEvents is that this is for


development/testing purposes only. It's not supposed to be used for
production code.

Event Targets
LessonDownloads
The EventTarget Interface
Do you remember the Node Interface and the Element interface from the first lesson?
Do you remember how the Element Interface is a descendant of the Node Interface,
and therefore inherits all of Node's properties and methods?

Well there was one piece that I totally skipped over then but am addressing now. The
Node Interface inherits from the EventTarget Interface.

The EventTarget Interface is inherited by all nodes and elements.


The MDN EventTarget page(opens in a new tab) says that EventTarget:

is an interface implemented by objects that can receive events and may have listeners
for them.
and

Element, document, and window are the most common event targets, but other objects
can be event targets too…
As you can see from the image above, the EventTarget is at the top of the chain. This
means that it does not inherit any properties or methods from any other interfaces.
However, every other interface inherits from it and therefore contain its properties and
methods. This means that each of the following is an "event target";

 the document object


 a paragraph element
 a video element
 etc.
Remember that both the document object and any DOM element can be an event
target. And again, why is this?...because both the Element Interface and the Document
Interface inherit from the EventTarget Interface. So any individual element inherits from
the Element Interface, which in turn inherits from the EventTarget Interface. Likewise,
the document object comes from the Document Interface, which in turn inherits from the
EventTarget Interface.

If you take a look at the EventTarget Interface, you'll notice that it doesn't
have any properties and only three methods! These methods are:

 .addEventListener()
 .removeEventListener()

 .dispatchEvent()

The one that we'll be looking at for the rest of this lesson will be
the .addEventListener() method.

Adding An Event Listener


We've taken a brief look at this hidden world of events. Using
the .addEventListener() method will let us listen for events and respond to them! I
just said, "listen for events". There are several ways to "phrase" this, so I want to give
some examples:

 listen for an event


 listen to an event
 hook into an event
 respond to an event

...all of these mean the same thing and are interchangeable with one another.

Let's use some pseudo-code to explain how to set an event listener:

<event-target>.addEventListener(<event-to-listen-for>, <function-to-
run-when-an-event-happens>);
So an event listener needs three things:

1. an event target - this is called the target


2. the type of event to listen for - this is called the type
3. a function to run when the event occurs - this is called the listener

The <event-target> (i.e. the target) goes right back to what we just looked at:
everything on the web is an event target (e.g. the document object, a <p> element,
etc.).

The <event-to-listen-for> (i.e. the type) is the event we want to respond to. It could
be a click, a double click, the pressing of a key on the keyboard, the scrolling of the
mouse wheel, the submitting of a form...the list goes on!

The <function-to-run-when-an-event-happens> (i.e. the listener) is a function to


run when the event actually occurs.

Let's transform the pseudo-code to a real example of an event listener:

const mainHeading = document.querySelector('h1');

mainHeading.addEventListener('click', function () {

console.log('The heading was clicked!');

});

Let's break down the snippet above:

 the target is the first <h1> element on the page


 the event type to listen for is a "click" event
 the listener is a function that logs "The heading was clicked!" to the console

Check out the MDN documentation for more info: addEventListener docs(opens in a
new tab).
Let's Add an Event Listener!
Show TranscriptSummarize Video

Demo Recap
In this demo, we:

1. Navigated to the MDN EventTarget.addEventListener()(opens in a new tab) page.


2. Added a click listener on the document :
document.addEventListener('click', function() {

console.log('The page was clicked');

})

3. Clicked on the page 22 times, which logged the "The page was clicked"
message to the console 22 times!

Add Event Listener to the Project


Running code in a browser's developer tools is fantastic for testing. But that event
listener will only last until the page is refreshed. As with all real JavaScript code that we
want to send to our users, our event listener code needs to be in a JavaScript file.

Let's try adding an Event Listener to our project's files!

Demo Recap
In this demo, we:

1. Opened the index.html file in our code editor to see where our app.js file is loaded.
2. Opened the app.js file and added an event listener:
document.addEventListener('click', function() {

console.log("you've clicked the document");

})
3. Loaded the HTML page in the browser (or reloaded it if it was already running) and
opened the console.
4. Clicked on the page to see the message in the console
5. Edited the event listener to target the <h1> element
document.addEventListener('click', function() {

// select the element

const mainHeading = document.querySelector('h1');

// change its background color to red

mainHeading.style.backgroundColor = 'red';

})

7. Refreshed the page to reload the app.js file and clicked again. The element's
background color turned to red!
8. Checked the DOM to confirm that the style background-color: red had been added to
the element.
This works just like it does when we run code in the console -- except now we
are running it in our JavaScript file so it will run whenever the page is loaded
or refreshed!
So far, we've only looked at the "click" event and a couple of other ones. When we
used the monitorEvents() function in the previous section, we saw a number of different
event types (e.g. dblclick , scroll , resize ).

How do you know what events are even out there to listen for? The answer is easy -
documentation! To see a full list of all of the possible events you can listen for, check
out the Events documentation: list of events(opens in a new tab)

Now It's Your Turn!


Let's add an event listener that changes the text of the h1 element to "Build an
AR App" when a user's mouse is over the h1 element -- and changes it back
to the original content when the mouse moves away from the element.
When you are done, it should look like this:
ou are done, it should look like this:

Which Event Should I Use?


Great question! You will want to use an event based on the actions of the mouse.
Explore the MDN Mouse Events(opens in a new tab) documentation to figure out how
to capture the mouse actions.

Hint: you'll need more than one event type to make this work.

Task List

Write all of your code in the app.js file of the replica home page project.

Review the MDN Mouse Events(opens in a new tab) documentation to determine


which event(s) to target.
Select the h1 element and use .addEventListener() to listen for an event on that
element.

Change the text of the h1 element to "Build an AR App" when a user's mouse is over
the h1 element.

Change the text of the h1 element back to "Learn ARKit" when a user's mouse moves
off of the h1 element.

In the browser, refresh the page to run the code in app.js .

Move your mouse over the h1 element to confirm that your code works

Add an Event Listener


LessonDownloads
My Solution
1. Select the h1 element:

// select the h1 element

const header = document.querySelector("h1");

2. Use textContext to retrieve the element's original text:

// store the original text in a variable

const originalText = header.textContent;

3. Declare a new variable to store the updated text

// store the updated text in a variable

const updatedText = "Build an AR app";

4. Add event listener to respond to moving the mouse over the selected element
('mouseover' event):

// add a listener for the mouse moving over the header


element

header.addEventListener("mouseover", function () {

header.textContent = updatedText;

});

5. Add event listener to respond to moving the mouse off of the selected element
('mouseout' event):

// add a listener for the mouse moving out of the header


element
header.addEventListener("mouseout", function () {
header.textContent = originalText;
});
Another way to do this is to use the mouseenter and mouseleave events:
// select the h1 element
const header = document.querySelector("h1");

// store the original text in a variable


const originalText = header.textContent;

// store the updated text in a variable


const updatedText = "Build an AR app";

// add a listener for the mouse moving over the header


element
header.addEventListener("mouseover", function () {
header.textContent = updatedText;
});

// add a listener for the mouse moving out of the header


element
header.addEventListener("mouseout", function () {
header.textContent = originalText;
});

Recap
In this section, you learned all about events, the EventTarget Interface, and how to add
event listeners. We used the .addEventListener() method to attach listeners to:

 the document
 a Node
 an Element

...basically anything that inherits from the EventTarget Interface. We also saw that there
are three main parts to an event listener:

1. an event target - the target

 the type of event to listen for - the type


 a function to run when the event occurs - the listener
Further Research
 addEventListener on MDN(opens in a new tab)
 EventTarget Interface(opens in a new tab)
 Introduction to events

Removing An Event Listener


We say that we can use an event target's .addEventListener() method to start
listening for specific events and respond to them. Let's say you only want to listen for
just the first click event, respond to it, and ignore all other click events.
The .addEventListener() event will listen for and respond to all click events.

(The newest version of the .addEventListener() specification does allow for an


object to be passed as a third parameter. This object can be used to configure how
the .addEventListener() method behaves. Of note, there is an option to listen for
only a single event. However, this configuration object is not widely supported just yet).

To remove an event listener, we use the .removeEventListener() method. It sounds


straightforward enough, right? However, before we look at .removeEventListener() ,
we need to take a brief review of object equality. It seems like an odd jump, but it'll
make sense in just a moment.

Removing An Event Listener


We say that we can use an event target's .addEventListener() method to start
listening for specific events and respond to them. Let's say you only want to listen for
just the first click event, respond to it, and ignore all other click events.
The .addEventListener() event will listen for and respond to all click events.
(The newest version of the .addEventListener() specification does allow for an
object to be passed as a third parameter. This object can be used to configure how
the .addEventListener() method behaves. Of note, there is an option to listen for
only a single event. However, this configuration object is not widely supported just yet).

To remove an event listener, we use the .removeEventListener() method. It sounds


straightforward enough, right? However, before we look at .removeEventListener() ,
we need to take a brief review of object equality. It seems like an odd jump, but it'll
make sense in just a moment.

Richard's Jacket vs Orit's Jacket


Even though two objects look exactly the same, that doesn't mean they're
identical. The same information does not indicate equality.

When working with JavaScript objects and equality, you need to determine if
they are they two separate objects or are they different names referring to the
same object.

avaScript and Type Coercion


Equality is a common task in most programming languages, but in JavaScript, it can be
a little bit tricky because JavaScript does this thing called type coercion where it will try
to convert the items being compared into the same type. (e.g. string, number,).
JavaScript has the double equality (==) operator that will allow type coercion. It also
has the triple equality (===) symbol that will prevent type coercion when comparing.

Hopefully, this is all review. But let's talk about just object equality, which includes
objects, arrays, and functions. Try giving these quizzes a shot:

Question 2 of 3
Given this code:

const a = {

myFunction: function quiz() { console.log('hi'); }


};

const b = {

myFunction: function quiz() { console.log('hi'); }

};

Does the following code evaluate to true or false?

a.myFunction === b.myFunction

true

false
Submit

Question 3 of 3
Given this code:

function quiz() { ... }

const a = {

myFunction: quiz

};

const b = {

myFunction: quiz

}
Does the following code evaluate to true or false?

a.myFunction === b.myFunction

true

false
Submit

So why do we care about any of this object/function equality? The reason is that
the .removeEventListener() method requires you to pass the same exact listener
function to it as the one you passed to .addEventListener().

Using .removeEventListener to Remove a Listener


Let's see some pseudo-code for the .removeEventListener() :

<event-target>.removeEventListener(<event-to-listen-for>,
<function-to-remove>);

An event listener needs three things:

1. an event target - this is called the target

 the type of event to listen for - this is called the type


 the function to remove - this is called the listener

Remember, the listener function must be the exact same function as the one used in
the .addEventListener() call...not just an identical looking function. Let's look at a couple
of examples.

This code will successfully add and then remove an event listener:
function myEventListeningFunction() {

console.log('howdy');

// adds a listener for clicks, to run the


`myEventListeningFunction` function

document.addEventListener('click',
myEventListeningFunction);

// immediately removes the click listener that should run


the `myEventListeningFunction` function

document.removeEventListener('click',
myEventListeningFunction);

Now, why does this work? It works because


both .addEventListener() and .removeEventListener :

 have the same target


 have the same type
 and pass the exact same listener

Now let's look at an example that would not work (it does not remove the event
listener):

// adds a listener for clicks, to run the


`myEventListeningFunction` function

document.addEventListener('click', function
myEventListeningFunction() {

console.log('howdy');

});
// immediately removes the click listener that should run
the `myEventListeningFunction` function

document.removeEventListener('click', function
myEventListeningFunction() {

console.log('howdy');

});

This code does not successfully remove the event listener. Again, why does
this not work?

 both .addEventListener() and .removeEventListener have the same target


 both .addEventListener() and .removeEventListener have the same type
 .addEventListener() and .removeEventListener have their own
distinct listener functions...they do not refer to the exact same function ( this is
the reason the event listener removal fails! )

Two functions can look the same, but live in two different places in memory. Looks can
be deceiving!
When we wrote

function myEventListeningFunction() {

console.log('howdy');

}
a second time, we actually created a completely new function that was stored in a
completely new location in memory! They may look the same and do the same thing,
but that doesn't make them the same. Imagine a scenario where you see two houses
that look exactly the same. While the houses might look the same, their addresses are
different! That's exactly what just happened in our previous example.

Why don't you try your hand at this!

Quiz Question
Assuming that myForm is a <form> element, will the <form> element have
a submit event listener after running the following code, or not?

myForm.addEventListener('submit', function
respondToSubmit(){...});
myForm.removeEventListener('submit', function
respondToSubmit(){...});

the element will have no event listeners

the element will still have an event listener


Submit

Demo Recap
In this demo, we:

1. Opened the app.js file and added an event listener which logs a message and
remove the first child element of the element with the #contain-all class:

document.addEventListener('keypress', function() {

console.log("removing first child");

document.querySelector('#contain-
all').firstElementChild.remove();

})
2. Found the #contain-all element, selected it and reviewed the Event Listeners panel.
No event listeners on that element!
3. Clicked on the Ancestors option. Now we can see our keypress event listener on
the body element.
4. Pressed a key on the page several times and watched elements disappear from the
page.

Using the Event Listeners tab


The Event Listeners tab in Dev Tools is helpful when you want to:

 Inspect all of the event listeners registered on that element.


 Inspect the event listeners registered on that element's ancestors.
 Remove the event listener for the current session. Note that it will be
registered again when the page reloads.
 Inspect the function that runs when the event listener is triggered.

Remove an Event Listener


LessonDownloads

Create a One-time Use Event Listener


There are some cases where we want to use an event listener just one time and then
disable the listener. Let's give it a try!

We're going to create an event listener that removes the last of the featured programs in
the section of the page with the hero_module class, and then removes itself so it
can't be used again.

This is also a good opportunity to get familiar with the Event Listeners tab in Dev
Tools. After you have written your event listener, go into the Event Listeners tab and
explore the listener you created:

 Find the function code


 Manually remove the listener using the Remove button.
Don't forget to reload the page to restore the listener.

Remove an Event Listener


LessonDownloads

My Solution
1. I selected the hero element:

// select hero_module element

const hero = document.querySelector('.hero__module');

2. I created function that runs a event listener to remove the last child element in
the hero module:

function removeElementOnce() {

hero.lastElementChild.remove();

3. I registered the event listener on the document :

document.addEventListener('click', removeElementOnce);

4. I tested my code. It works!!! But I'm not done yet because the listener is still
active after the first click.
Testing my event listener
It works -- but it isn't disabled after the first click

5. I added removeEventListener my event listener function to remove the


listener after it has been triggered the first time:

function removeElementOnce() {

hero.lastElementChild.remove();

document.removeEventListener('click',
removeElementOnce);
}

Now it works as expected!

Remove an Event Listener


LessonDownloads

Recap
In this section, you learned about how to remove event listeners. You took a dive into
object equality and how that plays a huge part in removing an event. Lastly, we also
looked at how you can find out what event listener a DOM element has by using the
DevTools.

What's Next?
Now that we've learned about adding and removing event listeners, it's time to learn
about the phases of an event!

Further Research
 removeEventListener on MDN(opens in a new tab)
 Easily jump to event listeners(opens in a new tab)
 Equality comparisons and sameness(opens in a new tab)
 Article: Object Equality in JavaScript(opens in a new tab)
 EventTarget Interface

Phases of an Event
LessonDownloads

Free Response
Thinking about nodes and how the DOM is structured, after running the code below,
which event listener will fire first when the page is clicked?

DO NOT RUN THE CODE YET. Just jot down your prediction and why you think your
prediction is correct.

document.addEventListener('click', function () {
console.log('The document was clicked');
});

document.body.addEventListener('click', function () {
console.log('The document body was clicked');
});

Submit

Event Phases
There are three different phases during the lifecycle of an event. They are:

 the capturing phase


 the at target phase
 and the bubbling phase

And they actually follow the order above; first, it's capturing, then at target, and then
the bubbling phase.

Most event handlers run during the at target phase, such as when you attach a click
event handler to the button. The event arrives at the button (its target), and there's only
a handler for it right there, so the event handler gets run.

But sometimes you have a collection of items -- such as a list -- and want to have one
handler cover every item (and still have the option of individual handlers for some
items.) By default, if you click on a child item and a handler doesn't intercept the click,
the event will "bubble" upward to the parent, and keep bubbling until something handles
it or it hits the document.

Capturing, on the other hand, lets the parent intercept an event before it reaches a
child.

Let's dig into these phases to see how they affect when events fire and the order they
fire in!

Example Code:
To see the phases of an event, let's use this HTML code as an example.

<html>

<body>

<div class = "container">

<p>

<button>Dare to click me?</button>

</p>

</div>

</body>

</html>

1. Clicking on the event starts the capturing phase at the html tag, working its
way down to the element that was clicked.
2. When it reached the element that was clicked, it's in the target phase.
3. Then it switches to the bubbling phase and works its way back to the html tag.
The three event phases of an event: capturing, at target, and bubbling.

Which Phase is Used?


LessonDownloads

So of the three phases in an event, which one does the .addEventListener() method
actually use? And, how can we change it?

Up until this point, we've only seen the .addEventListener() method called
with two arguments, the:

 event type
 and the listener

document.addEventListener('click', function () {
console.log('The document was clicked');

});

There's actually a third argument to the .addEventListener() method;


the useCapture argument. From it's name, you'd think that if this argument were left
out, .addEventListener() would default to using the capturing phase. This is an
incorrect assumption! By default, when .addEventListener() is called with only
two arguments, the method defaults to using the bubbling phase.

The code below uses .addEventListener() with only two arguments, so it will invoke
the listener during the bubbling phase:

document.addEventListener('click', function () {

console.log('The document was clicked');

});

However, in this code, .addEventListener() is called with three arguments with the
third argument being true (meaning it should invoke the listener earlier, during the
capturing phase!).

document.addEventListener('click', function () {
console.log('The document was clicked');
}, true);
Testing my event listener again
Now it works only on the first click

6. I refreshed the page and explored the Event Listeners tab in Dev Tools to find
the function that is triggered when the page is clicked and then manually
removed the event listener.

HINT: Remember the event listener is registered to document so you'll need to toggle
on the Ancestors button on so you can see the event listener.
View the function and remove the listener in the Event Listeners tab

Event Handler Setup for Different Phases


We're using the same HTML code:

HTML
<html>

<body>

<div class = "container">

<p>

<button>Dare to click me?</button>

</p>
</div>

</body>

</html>

And adding event listeners for different phases:

Capturing
The true parameter at the end of the .addEventListener method makes the
event respond in the capturing phase:
// runs first in capturing phase

document.querySelector('p').addEventListener('click', function () {

console.log('<p> - capture phase');

}, true);

Bubbling
These listeners will fire in the bubbling phase because that is the default
for .addEventListener :

// runs last after event bubbles back to the top

document.querySelector('body').addEventListener('click', function () {

console.log('<body> - bubbling phase');

});

// runs second after target phase is completed and bubbling phase starts

document.querySelector('button').addEventListener('click', function () {

console.log('<button> - bubbling phase');

});

The event finishes when it reaches the html element at the top of the chain.
Quizzes: Event Phases
LessonDownloads

Question 1 of 2
Look at the code below. In which phase will the event fire?

const items = document.querySelectorAll('.quizzing-quizzes');


const el = items[1];

el.addEventListener('click', function () {
console.log('You clicked on the 2nd quizzing-quizzes item!');
}, false);

the capturing phase

the target phase

the bubbling phase


Submit

Now that you have a little more knowledge about the "capturing", "at target", and
"bubbling" phases, we're going to go back to the question at the beginning of this
section.

Question 2 of 2
After running the code below and clicking on the page, two console.log
messages will display in the console. Put the messages in the correct order.

document.addEventListener('click', function () {
console.log('The document was clicked');
});

document.body.addEventListener('click', function () {
console.log('The body element was clicked');
});
The body element was clicked.
The document was clicked.

Order of Messages

console.log Message
First Message
Second Message
Submit

The Event Object


LessonDownloads

The Event Object


Now that you know that event listeners fire in a specific order and how to interpret and
control that order, it's time to shift focus to the details of the event itself.

When an event occurs, the browser includes an event object. This is just a regular
JavaScript object that includes a ton of information about the event itself. According to
MDN, the .addEventListener() 's listener function receives:

a notification (an object that implements the Event interface) when an event of the
specified type occurs
Up until this point, I've been writing all of the listener functions without any parameter to
store this event object. Let's add a parameter so we can store this important
information:

document.addEventListener('click', function (event) { //


← the `event` parameter is new!

console.log('The document was clicked');

});

Notice the new event parameter that's been added to the listener function. Now when
the listener function is called, it is able to store the event data that's passed to it!

💡 An "event" is an "evt" is an "e" 💡


Remember that a function's parameter is just like a regular variable. In the following
example, I'm using a parameter with the name event .

const items = document.querySelectorAll('.quizzing-


quizzes');

const el = items[1];

el.addEventListener('keypress', function (event) {

console.log('You clicked on the 2nd quizzing-quizzes


item!');

});

Instead of event , the parameter's name could just as easily be:

 evt
 e

 theEvent

 horse
The name event or evt does not provide any inherent meaning or special capabilities;
there is nothing special to the name... it's just the name of the parameter. Feel free to
give it any name that's informative or descriptive!

The Mouse Event Object


Show TranscriptSummarize Video

Demo Recap
In this demo, we:

1. Added an event listener to log out a click event

document.addEventListener('click', function (event) {

console.log(event);

});

2. Opened the logged event in the console and explored it. We looked at:
 pageX and pageY which give us the coordinates of the click event on the
page
 type which gave us the type of the event

3. We navigated to the MDN MouseEvent Interface(opens in a new tab) page to


learn more about the properties we were seeing.

💡 Are you seeing a PointerEvent and not a MouseEvent?💡


The most recent versions of most browsers will now return a PointerEvent rather than
a MouseEvent . For our purposes, they are essentially the same
thing. PointerEvent inherits from MouseEvent which means that it has all
of MouseEvent properties and methods and properties and some new ones that are
specific to PointerEvent .
PointerEvent was created to support other types of input devices including pens,
styluses and touch surfaces.

You can compare the two by reviewing the documentation:

 MDN documentation for PointerEvent(opens in a new tab)


 MDN documentation for MouseEvent(opens in a new tab)

The Default Action


As we just looked at, the event object stores a lot of information, and we can use this
data to do all sorts of things. However, one incredibly common reason that
professionals use the event object for, is to prevent the default action from happening.
That sounds like an odd thing to do, but let's explore this.

Think about an anchor link on a webpage. There are probably a couple dozen links on
this page! What if you wanted to run some code and display some output when you
click on one of these links. If you click on the link, it will automatically navigate you to
the location listed in its href attribute: that's what it does by default.

What about a form element? When you submit a form, by default, it will send the data to
the location in its action attribute. What if we wanted to validate the data before
sending it, though?

Without the event object, we're stuck with the default actions. However, the event object
has a .preventDefault() method on it that a handler can call to prevent the default
action from occurring!

const link = document.querySelector('#my-classroom');

link.addEventListener('click', function (event) {


event.preventDefault();

console.log("Hurray! We didn't navigate to a new


page!");

});

Try This!
Load the replica homepage project in the browser and click the My Classroom link in
the uppper-right corner. The browser will navigate to your Udacity classroom.

Now add this code to app.js and reload the page.

const link = document.querySelector('#my-classroom');

link.addEventListener('click', function (event) {

event.preventDefault();

console.log("Wow! We didn't navigate to a new


page!");

});

What happens now? You should see the message in the console and you should stay
on the replica home page.

Quiz Question
Any event that is cancelable will be stopped with .preventDefault() . Which of
these are cancelable?

Hint: If you aren't sure, check out the W3C documentation: List of Event
Types(opens in a new tab)
click

mouseenter

mouseover

load

keyup
Submit

Events
LessonDownloads

Recap
We covered a number of important aspects of events and event listeners in this section!
We looked at:
 the phases of an event:
 the capturing phase
 the at target phase
 the bubbling phase
 the event object
 prevent the default action with .preventDefault()

Further Research
 Event dispatch and DOM event flow(opens in a new tab) on W3C
 capture phase(opens in a new tab) on W3C
 target phase(opens in a new tab) on W3C
 bubble phase(opens in a new tab) on W3C
 Event(opens in a new tab) on MDN
 Event reference(opens in a new tab) on MDN
 addEventListener(opens in a new tab) on MDN

The Problem of Too Many Events


LessonDownloads

How many event listeners are created with this code?

const myCustomDiv = document.createElement('div');

for (let i = 1; i <= 200; i++) {

const newElement = document.createElement('p');

newElement.textContent = 'This is paragraph number '


+ i;
newElement.addEventListener('click', function
respondToTheClick(evt) {

console.log('A paragraph was clicked.');

});

myCustomDiv.appendChild(newElement);

document.body.appendChild(myCustomDiv);

Enter only the number!

Submit

Loops Can Create A Lot of Events!


Show TranscriptSummarize Video

Demo Recap
In this demo we

1. Added the code from the quiz above to the app.js file in our replica web
page:

// create a new div element

const myCustomDiv = document.createElement('div');


for (let i = 1; i <= 200; i++) {

// create a new paragraph element

const newElement = document.createElement('p');

// add text to the paragraph

newElement.textContent = 'This is paragraph number '


+ i;

// register an event listener to the paragraph


element

newElement.addEventListener('click', function
respondToTheClick(evt) {

console.log('A paragraph was clicked.');

});

// append the paragraph to the new div element

myCustomDiv.appendChild(newElement);

// append the new div element to the page

document.body.appendChild(myCustomDiv);

2. Refreshed the page, which added 200 new elements to the bottom of the page
3. Inspected the event listener on the paragraph elements.
All of the paragraphs have the an identical click event listener -- and each listener
creates a new, identical respondToTheClick function, like this:
There must be a better way...

Refactoring The Number of Event Listeners


Let's look at the code again:

const myCustomDiv = document.createElement('div');

for (let i = 1; i <= 200; i++) {

const newElement = document.createElement('p');


newElement.textContent = 'This is paragraph number '
+ i;

newElement.addEventListener('click', function
respondToTheClick() {

console.log('A paragraph was clicked.');

});

myCustomDiv.appendChild(newElement);

document.body.appendChild(myCustomDiv);

We're creating a <div> element, attaching two hundred paragraph elements and
attaching an event listener with a respondToTheClick function to each paragraph as we
create it. There are a number of ways we could refactor this code. For example, as of
right now, we're creating two hundred different respondToTheClick functions (that all
actually do the exact same thing!). We could extract this function and just reference the
function instead of creating two hundred different functions:

const myCustomDiv = document.createElement('div');

function respondToTheClick() {
console.log('A paragraph was clicked.');
}

for (let i = 1; i <= 200; i++) {


const newElement = document.createElement('p');
newElement.textContent = 'This is paragraph number '
+ i;

newElement.addEventListener('click',
respondToTheClick);
myCustomDiv.appendChild(newElement);
}

document.body.appendChild(myCustomDiv);

Better! One listener helps reduce complexity but we still have too many listeners
This is a great step in the right direction!

However, we still have two hundred event listeners. They're all pointing to the same
listener function, but there are still two hundred different event listeners.

What if we moved all of the listeners to the <div> instead?


Much better! Now we have one function and one listener
The code for this would look like:

const myCustomDiv = document.createElement('div');

function respondToTheClick() {

console.log('A paragraph was clicked.');

for (let i = 1; i <= 200; i++) {


const newElement = document.createElement('p');

newElement.textContent = 'This is paragraph number '


+ i;

myCustomDiv.appendChild(newElement);

myCustomDiv.addEventListener('click', respondToTheClick);

document.body.appendChild(myCustomDiv);

Now there is only:

 a single event listener


 a single listener function

Now the browser doesn't have to store in memory two hundred different event listeners
and two hundred different listener functions. That's great for performance`!

However, if you test the code above, you'll notice that we've lost access to the individual
paragraphs. There's no way for us to target a specific paragraph element. So how do
we combine this efficient code with the access to the individual paragraph items that we
did before?

We use a process called event delegation.

Event Delegation
LessonDownloads
Event Delegation
Remember the event object that we looked at in the previous section? That's our ticket
to getting back the original functionality!

The event object has a .target property. This property references the target of the
event. Remember the capturing, at target, and bubbling phases?...these are coming
back into play here, too!

Let's say that you click on a paragraph element. Here's roughly the process that
happens:

1. a paragraph element is clicked

 the event goes through the capturing phase


 it reaches the target
 it switches to the bubbling phase and starts going up the DOM tree
 when it hits the <div> element, it runs the listener function
 inside the listener function, event.target is the element that was clicked

So event.target gives us direct access to the paragraph element that was clicked.
Because we have access to the element directly, we can access its .textContent ,
modify its styles, update the classes it has - we can do anything we want to it!

const myCustomDiv = document.createElement('div');

function respondToTheClick(evt) {
console.log('A paragraph was clicked: ' +
evt.target.textContent);
}

for (let i = 1; i <= 200; i++) {


const newElement = document.createElement('p');
newElement.textContent = 'This is paragraph number '
+ i;

myCustomDiv.appendChild(newElement);
}

document.body.appendChild(myCustomDiv);

myCustomDiv.addEventListener('click', respondToTheClick);

Checking the Node Type in Event Delegation


In the code snippet we used above, we added the event listener directly to
the <div> element. The listener function logs a message saying that a paragraph
element was clicked (and then the text of the target element). This works perfectly!
However, there is nothing to ensure that it was actually a <p> tag that was clicked
before running that message. In this snippet, the <p> tags were direct children of
the <div> element, but what happens if we had the following HTML:

<article id="content">

<p>Brownie lollipop <span>carrot cake</span> gummies


lemon drops sweet roll dessert tiramisu. Pudding muffin
<span>cotton candy</span> croissant fruitcake tootsie
roll. Jelly jujubes brownie. Marshmallow jujubes topping
sugar plum jelly jujubes chocolate.</p>

<p>Tart bonbon soufflé gummi bears. Donut marshmallow


<span>gingerbread cupcake</span> macaroon jujubes muffin.
Soufflé candy caramels tootsie roll powder sweet roll
brownie <span>apple pie</span> gummies. Fruitcake danish
chocolate tootsie roll macaroon.</p>

</article>

In this filler text(opens in a new tab) , notice that there are some <span> tags. If we
want to listen to the <article> for a click on a <span> , you might think that this
would work:

document.querySelector('#content').addEventListener('clic
k', function (evt) {
console.log('A span was clicked with text ' +
evt.target.textContent);

});

This will work, but there's a major flaw. The listener function will still fire when either one
of the paragraph elements is clicked, too! In other words, this listener function is not
verifying that the target of the event is actually a <span> element. Let's add in this
check:

document.querySelector('#content').addEventListener('clic
k', function (evt) {

if (evt.target.nodeName === 'SPAN') { // ← verifies


target is desired element

console.log('A span was clicked with text ' +


evt.target.textContent);

});

Remember that every element inherits properties from the Node Interface(opens in a
new tab). One of the properties of the Node Interface that is inherited is .nodeName .
We can use this property to verify that the target element is actually the element we're
looking for. When a <span> element is clicked, it will have a .nodeName property
of "SPAN" , so the check will pass and the message will be logged. However, if
a <p> element is clicked, it will have a .nodeName property of "P" , so the check
will fail and the message will not be logged.

⚠️The nodeName 's Capitalization ⚠️


The .nodeName property will return an uppercase string, not a lowercase one. So
when you perform your check make sure to either:

 check for capital letters


 convert the .nodeName to lowercase
// check using capital letters
if (evt.target.nodeName === 'SPAN') {
console.log('A span was clicked with text ' +
evt.target.textContent);
}

> // convert nodeName to lowercase


if (evt.target.nodeName.toLowerCase() === 'span') {
console.log('A span was clicked with text ' +
evt.target.textContent);
}

Question 1 of 2
Review the HTML below:

<div class="container">

<ul>

<li class="items" id="item-1">Remove Item 1</li>

<li class="items" id="item-2">Remove Item 2</li>

<li class="items" id="item-3">Remove Item 3</li>

<li class="items" id="item-4">Remove Item 4</li>

</ul>

</div>

Which of these code snippets would remove the first list item?

document.querySelector('.container').addEventListener('click',
function (e) {
if (e.target.className == 'items') {
e.target.remove();
}
});

document.querySelector('.container').addEventListener('click',
function (e) {
if (e.target.id == 'item-1') {
e.target.remove();
}
});

document.querySelector('.container').addEventListener('click',
function (e) {
e.target.remove();
});
Submit

Question 2 of 2
Review the HTML below:

<div class="container">

<ul>

<li class="items" id="item-1">Remove Item 1</li>

<li class="items" id="item-2">Remove Item 2</li>

<li class="items" id="item-3">Remove Item 3</li>

<li class="items" id="item-4">Remove Item 4</li>

</ul>

</div>
Which of these code snippets would remove ONLY the first list item?

document.querySelector('.container').addEventListener('click',
function (e) {
if (e.target.id == 'item-1') {
e.target.remove();
}
});

document.querySelector('.container').addEventListener('click',
function (e) {
if (e.target.className == 'items') {
e.target.remove();
}
});

document.querySelector('.container').addEventListener('click',
function (e) {
e.target.remove();
});

document.querySelector('.container').addEventListener('click',
function (e) {
if (e.target.textContent.includes('Item 1')) {
e.target.remove();
}
});
Submit

Add Favorites Buttons


LessonDownloads

Add Buttons to Select Favorite Nanodegrees


Students often take multiple Nanodegrees so we're thinking about adding a feature to allow them
to select their favorites.

In this exercise, we will add buttons to the Nanodegree cards in the section of the page with
the list-nanodegrees class.

Your tasks will involve:

 Creating and styling the buttons.


 Selecting the right place to add a button to each Nanodegree card.
 Adding the event listener to the correct part of the page. For efficiency, we only want to add one event
listener to one element on the page.
 Writing a function to toggle the text on the button between Add to Favorites and Remove from
Favorites when the button is clicked
 Adding/removing a favorite status indicator, e.g. ⭐ ⭐ ⭐ , to show when a program has been chosen as a
favorite.
 Preventing the default action of navigating to the Nanodegree program page when the button is clicked
while allowing the default action to proceed when any other part of the button is clicked.

There is a lot to do here! This section will test many of the skills you have used so far:

 Selecting elements
 Creating new elements and appending them to the page
 Updating elements
 Removing elements
 Preventing default actions
 Using event delegation and event targets
When you are done, the Nanodegree list section should look like this:

A Few Hints
 Think about which element to target for your NodeList. You'll want to select an element where you can
use appendChild to add the button to the card after the title and before the affiliates.
 Think about where to use preventDefault . You'll want the user to be able to navigate to the
Nanodegree page to learn more about it when they click any part of the card other than the button.

 Style the buttons using existing classes. The button and button--primary classes will apply the
same styles as the rest of the buttons o the page.
 Think outside the box when you are removing the favorite status indicator. There are many ways to do
this, but the simplest is to directly target the element you want to remove. You should be familiar with
the parent and child properties of the Node Interface(opens in a new tab) -- but did you know that
there are sibling properties too?

Task List
Write all of your code in app.js .

Select elements to create a NodeList that holds the nodes you'll use to append the favorite
buttons.

Use createElement to create the button elements.

Solution: Add Favorites Buttons


LessonDownloads

My Solution

Step 1: Select the elements to work with


I selected all of the Nanodegree card titles and saved them as a NodeList.

I decided to use the card--nanodegree__title elements because they would allow me to


append the button after the title and before the affilates.

// select all of the Nanodegree card titles

const ndList = document.querySelectorAll('.card--


nanodegree__title');

Step 2: Create a button for each element in NodeList


I looped through the NodeList and in each element, I:
 Created A button using .createElement
 Used .textContent to add the starting text
 Used .classList to add the two styles I needed to make the buttons look like
the rest of the buttons the page.
 Appended each button element to the NodeList element using appendChild

// create an "Add to Favorites" button on each card after


the title

ndList.forEach(function (nd) {

const button = document.createElement('button');

button.textContent = 'Add to Favorites';

button.classList = 'button button--primary';

nd.appendChild(button);

});

Step 3: Write the function to toggle favorite status


1. I created a helper variable to hold the target. That is an optional step, but
often helpful when you will be using the event target multiple times:

function toggleFavorite(event) {

const target = event.target;

1. I checked to see if the target is a button element. Because we only want to


add one event listener on one element, I need to ensure that my code will only
run when the button is clicked:

if (target.nodeName === 'BUTTON') {

1. Once I've confirmed that the user clicked the button, I want to run the code to
prevent the default action of navigating away from the page:
event.preventDefault();

1. I checked to see if the item is already a favorite. If it isn't, I change the text and
create a new p element to hold the favorite status, and append the new
element to the page:

if (target.textContent.startsWith('Add')) {

event.target.textContent = 'Remove from


favorites';

const fav = document.createElement('p');

fav.textContent = '⭐ ⭐ ⭐ ';

target.parentElement.appendChild(fav);

1. If the item is already a favorite, I need to change the text back to the original
text and remove the favorite status indicator using the
target's nextSibling property:

} else {

event.target.textContent = 'Add to favorites';

target.nextSibling.remove();

All together, the function looks like this:

function toggleFavorite(event) {

// create a helper variable to hold the target

const target = event.target;

// check if the target is the button


if (target.nodeName === 'BUTTON') {

// stop the default behavior (navigating to the


nanodegree page)

event.preventDefault();

// check if the this is already a favorite

if (target.textContent.startsWith('Add')) {

// change the text to "Remove"

event.target.textContent = 'Remove from


favorites';

// create a an element to hold the favorite


status indicator

const fav = document.createElement('p');

fav.textContent = '⭐ ⭐ ⭐ ';

// append the fav element to the title

target.parentElement.appendChild(fav);

} else {

// change the text back to "Add"

event.target.textContent = 'Add to
favorites';

// remove the favorite status indicator

target.nextSibling.remove();

}
}

Step 4: Add an event listener that triggers the favorite


status function
I selected the Nanodegree list element and added an event listener. I chose to do this in
two steps because I think it is easier to read:

const ndsContainer = document.querySelector('.list-


nanodegrees');
ndsContainer.addEventListener('click', toggleFavorite);

Recap: Event Delegation


LessonDownloads

Recap
In this section, we looked at Event Delegation. Event Delegation is the process of
delegating to a parent element the ability to manage events for child elements. We were
able to do this by making use of:

 the event object and its .target property


 the different phases of an event

Further Research
 Article: Event delegation(opens in a new tab)
 Article: How JavaScript Event Delegation Works

Script Tag Placement Matters!


When the script tag for the JavaScript page was placed near the end of the HTML file
everything worked as expected.
But when we moved the script tag to the head, everything broke. This happened
because the DOM wasn't ready to be manipulated when the JavaScript code started
running.

In this section, we'll look at why this happens and how to avoid this problematic
situation.

The DOM Is Built Incrementally


Do you remember the video we watched of Illya from Google explaining how the DOM
is parsed? A key thing to point out is that when the HTML is received and converted into
tokens and built into the document object model, is that this is a sequential process.
When the parser gets to a <script> tag, it must wait to download the script file and
execute that JavaScript code. This is the important part and the key to why the
placement of the JavaScript file matters!

Let's look at some code to show (more or less) what's happening. Take a look at this
initial part of an HTML file:

<!DOCTYPE html>

<html lang="en">

<head>

<link rel="stylesheet" href="/css/styles.css" />

<script>

document.querySelector('footer').style.backgroundColor =
'purple';

</script>

This isn't the full HTML file...BUT, it's all that's been parsed so far. Notice at the bottom
of the code that we have so far is a <script> file. This is using inline JavaScript rather
than pointing to an external file. The inline file will execute faster because the browser
doesn't have to make another network request to fetch the JavaScript file. But the
outcome will be exactly the same for both this inline version and if the HTML had linked
to an external JavaScript file.

Do you see the JavaScript/DOM code in the <script> tags? Take a second and read
it again:

document.querySelector('footer').style.backgroundColor =
'purple';

Does anything jump out at you about this code? Anything at all? This code is completely
error-free...unfortunately, when it runs, it will still cause an error. Any ideas why?

The problem is with the .querySelector() method. When it runs...there's


no <footer> element to select from the constructed document object model yet! So
instead of returning a DOM element, it will return null . This causes an error because it
would be like running the following code:

null.style.backgroundColor = 'purple';

null doesn't have a .style property, so thus our error is born.

Quiz Question
Take a look at this code. When will an error be thrown?
HTML

<html>

<head>

<meta charset="utf-8">

<meta name="viewport" content="width=device-width,


initial-scale=1">

<title>Script Placement Quiz</title>

<script src="app.js"></script>
</head>

<body>

<div class="container">

<p>

<button>Click Me!</button>

</p>

</div>

</body>

</html>

JavaScript

const myButton = document.querySelector('button');

myButton.addEventListener('click', function () {
myButton.style.backgroundColor = 'red';
});

When this code runs:

const button = document.querySelector('button');

When this code runs:

myButton.addEventListener('click', function () {
When the button is clicked and JavaScript tries to run this code:

myButton.style.backgroundColor = 'red';

The code will run as expected. When a user clicks on the button its background color
will turn red and no error will be thrown.
Submit

Script Placement Solves the Problem!


If we move the script tag with the JavaScript file down to the bottom of the page, the
error has been solved.

Think about why this would make things work. Well, if the DOM is built sequentially, if
the JavaScript code is moved to the very bottom of the page, then by the time the
JavaScript code is run, all DOM elements will already exist!

Is There Another Solution?


Glad you asked! Of course there is! An alternative solution would be to use browser
events! 🙌🏼

We'll learn how to do that next!

DOMContentLoaded
LessonDownloads
The Content Is Loaded Event
When the document object model has been fully loaded, the browser will fire an event.
This event is called the DOMContentLoaded event, and we can listen for it the same
way we listen to any other events:

document.addEventListener('DOMContentLoaded', function () {
console.log('the DOM is ready to be interacted with!');
});
Show TranscriptSummarize Video

Demo Recap
In this demo we:

1. Opened Dev Tools and navigated to the Network pane.


2. Refreshed the page and looked for the DOMContentLoaded message at the
bottom of the Network pane.
3. Found the blue bar in time line that represents the DOMContentLoaded event
in the timeline and the other blue line in the Waterfall section of the pane.
The Network pane of DevTools with the DOMContentLoaded indicators highlighted.

Question 1 of 2
We want to add an event listener to trigger a notification for
the DOMContentLoaded event. Where should we register the listener?
On the document object

On the body object

On anything that inherits the Element interface


Submit

Using the DOMContentLoaded Event


Because we now know about the DOMContentLoaded event, we can use it
to keep our JS code in the <head> .

Let's update the previous HTML code to include this event:

<!DOCTYPE html>

<html lang="en">

<head>

<link rel="stylesheet" href="/css/styles.css" />

<script>

document.addEventListener('DOMContentLoaded', function () {

document.querySelector('footer').style.backgroundColor = 'purple';
});

</script>

Pretty cool, right?!? We have the JavaScript code in the <head> element, but it is
now wrapped in an event listener for the DOMContentLoaded event. This will
prevent the DOM-styling code from running when the browser gets to it. Then, when the
DOM has been constructed, the event will fire and this code will run.

If you're looking at somebody else's code, you may see that their code listens for
the load event being used instead (e.g. document.onload(...) ). load fires later
than DOMContentLoaded -- load waits until all of the images, stylesheets, etc.
have been loaded (everything referenced by the HTML.) Many older developers
use load in place of DOMContentLoaded as the latter wasn't supported by the very
earliest browsers. But if you need to detect when your code can
run, DOMContentLoaded is generally the better choice.

However, just because you can use the DOMContentLoaded event to write
JavaScript code in the <head> that doesn't mean you should do this. Doing it this
way, we have to write more code (all of the event listening stuff) and more code is
usually not always the best way to do something. Instead, it would be better to move the
code to the bottom of the HTML file just before the closing </body> tag.

So when would you want to use this technique? Well, JavaScript code in
the <head> will run before JavaScript code in the <body> , so if you do have
JavaScript code that needs to run as soon as possible, then you could put that code in
the <head> and wrap it in a DOMContentLoaded event listener. This way it will
run as early as possible, but not too early that the DOM isn't ready for it.

Let's Revisit The Loading Problem


Question 2 of 2
How can we fix this code so that it will run as expected without any errors?
HTML

<html>
<head>

<meta charset="utf-8">

<meta name="viewport" content="width=device-width, initial-scale=1">

<title>Script Placement Quiz</title>

<script src="app.js"></script>

</head>

<body>

<div class="container">

<p>

<button>Click Me!</button>

</p>

</div>

</body>

</html>

JavaScript

const myButton = document.querySelector('button');

myButton.addEventListener('click', function () {
myButton.style.backgroundColor = 'red';
});

Move the script tag to right before the closing </body> tag
Keep the script tag in the <head> element and add
a DOMContentLoaded listener to the top of the JavaScript file, like this:

document.addEventListener('DOMContentLoaded', function () {
console.log('the DOM is ready!');
});

const myButton = document.querySelector('button');

myButton.addEventListener('click', function () {
myButton.style.backgroundColor = 'red';
});

Keep the script tag in the <head> element and wrap the JavaScript code in
a DOMContentLoaded listener, like this:

document.addEventListener('DOMContentLoaded', function () {
const myButton = document.querySelector('button');

myButton.addEventListener('click', function () {
myButton.style.backgroundColor = 'red';
});
});
Submit

Recap
In this section, we learned about the helpful DOMContentLoaded event.
Along the way, we reviewed how the HTML code is parsed incrementally and how this
affects JavaScript/DOM code. We also looked at why writing DOM-manipulation code in
the <head> can cause errors.

Further Research
 DOMContentLoaded Event docs on MDN(opens in a new tab)

What You Learned:


In this lesson we explored the secret world of events that happen when yoyu
interact with a web page. We covered:

 The event lifecycle


 Listening for events using JavaScript
 Using the data the is generated in an event
 Preventing an event from triggering multiple responses
 Knowing when the DOM is ready for our code

You now know how to use JavaScript to interact with the browser.
Congratulations on your new superpower!

Certification Assessment

Tips to Pass the Certification Assessment


By following the below tips you maximize your chances of passing the Certification
Assessment and getting the certificate. Please note that if you don't pass the
assessment you can keep reattempting it until you pass it!
Certification Assessment Instructions
The Certification Assessment is your way to get your Certificate of Completion for the
Challenge phase of this program. Here is what you need to know about the Certification
Assessment:

 The Certification Assessment is completely online.


 The Certification Assessment will test the skills you learned from the
Challenge phase of this program.
 You must sit for the Certification Assessment within 8 weeks (or less,
depending on when you enrolled) from the date you enrolled.
 The Certification Assessment duration is 60 minutes only from the moment
you start the assessment. You’ll be able to see a countdown timer on the
screen. Please note that you can’t pause the time, and once the timer reaches
0 seconds, the assessment will be automatically submitted. The Certification
Assessment consists of 20 multiple choice questions (MCQs) about your track
content.
 You cannot skip any question or return to any previous one. So, make
sure you take the time to thoughtfully answer each question while keeping
track of the timer.
 You will be eligible to receive a “Certificate of Completion” in your track if you
pass the Certification Assessment with a minimum score of 60%. In case you
do not pass the first time, you will be able to reattempt the Certification
Assessment until you pass as long as you’re within your allotted program
duration.
 You will be able to take the Certification Assessment, as well as reattempting
it (when you don’t pass it) from within your classroom through the button
below, as long as you’re still within your allowed duration in the program.

Start the Certification Assessment(opens in a new tab)


We hope you continue to inspire the world with what you’ve learned and once again we
wish you all the best in your future endeavors!

You might also like