[go: up one dir, main page]

0% found this document useful (0 votes)
91 views308 pages

WDD 131 Dynamic Web Fundamentals

The document outlines the curriculum for WDD 131 Dynamic Web Fundamentals, covering essential topics such as JavaScript, CSS, HTML, and web design principles. It includes detailed chapters on JavaScript variables, constructs, the Document Object Model (DOM), responsive design, and debugging techniques. Additionally, it provides guidelines for file naming conventions and structuring web projects effectively.

Uploaded by

Carlos Medina
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)
91 views308 pages

WDD 131 Dynamic Web Fundamentals

The document outlines the curriculum for WDD 131 Dynamic Web Fundamentals, covering essential topics such as JavaScript, CSS, HTML, and web design principles. It includes detailed chapters on JavaScript variables, constructs, the Document Object Model (DOM), responsive design, and debugging techniques. Additionally, it provides guidelines for file naming conventions and structuring web projects effectively.

Uploaded by

Carlos Medina
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/ 308

WDD 131 Dynamic Web

fundamentals
Contents
Chapter 1 Introduction to JavaScript, Javascript variables............................5
1.1 Hosting on GitHub................................................................................5
1.2 File and folder naming conventions.....................................................5
1.2.1 Naming Conventions....................................................................6
1.2.2 Dealing with files..........................................................................8
1.3 HTML and CSS review.........................................................................11
1.4 JavaScript Introduction.......................................................................11
1.5 JavaScript: Variables...........................................................................21
1.6 Template literals (template strings)....................................................29
1.7 Adding last modification and prorated year.......................................39
1.8 Navigation Menu example..................................................................40
Chapter 2 CSS media queries, JavaScript Constructs, The Document Object
Model (DOM) interface, Handling DOM effects, Responsive Menus, JavaScript
debugging 43
2.1 CCS media queries..............................................................................43
2.1.1 Prepare.......................................................................................44
2.1.2 Activity instructions....................................................................45
2.2 JavaScript Construtcs..........................................................................52
2.2.1 Common controls structures or building blocks in JavaScript....52
2.2.2 Loops and iteration.....................................................................64
2.2.3 Examples....................................................................................77
2.3 The Document Object model (DOM) interface...................................81
2.3.1 The JavaScript DOM explained in 5 minutes...............................82
2.3.2 Manipulating documents...........................................................82
2.3.3 Activity Instructions....................................................................98
2.4 Handling DOM events......................................................................100
2.4.1 JavaScripts Events.....................................................................101
2.4.2 DOM EVENTS - Ponder activities.............................................106
2.4.3 Some common DOM event concepts/use cases.......................114
2.5 Responsive menus............................................................................117
2.6 Debugging – What went wrong........................................................122
Chapter 3 Design principles, CSS Concepts: Pseudo Selection, Image file
formats for the web, Responsive images, Java script Arrays, JavaScript
Functions 127
3.1 Design principles..............................................................................127
3.1.1 8 fundamental principles of effective Web Design...................127
3.1.2 Learn the most common Design mistakes by Non Designers...129
3.1.3 Web design principles summary...............................................131
3.2 CSS Concepts: Pseudo Selection.......................................................132
3.2.1 Pseudo-classes..........................................................................132
3.2.2 :root Pseudo-Class....................................................................148
3.2.3 CSS Pseudo-elements...............................................................149
3.3 Image file formats for the web.........................................................160
3.3.1 Common image formats...........................................................160
3.3.2 WebP image format..................................................................161
3.3.3 Image file type and format guide.............................................161
3.3.4 Image optimization...................................................................161
3.4 Responsive images...........................................................................164
3.5 Java script Arrays..............................................................................171
3.5.1 Creating an array......................................................................171
3.5.2 ARRAY.......................................................................................171
3.5.3 DESCRIPTION............................................................................171
3.5.4 CONSTRUCTOR.........................................................................179
3.5.5 STATIC PROPERTIES...................................................................180
3.5.6 STATIC METHODS......................................................................180
3.5.7 INSTANCE PROPERTIES.............................................................180
3.5.8 INSTANCE METHODS................................................................181
3.5.9 EXAMPLES.................................................................................185
3.5.10 Examples of using array methods with applications to real life191
3.5.11 Summary..................................................................................191
3.6 JavaScript Functions.........................................................................192
3.6.1 Defining functions....................................................................193
3.6.2 Calling functions.......................................................................196
3.6.3 Function scope.........................................................................198
3.6.4 Scope and the function stack....................................................199
3.6.5 Closures....................................................................................199
3.6.6 Using the arguments object.....................................................199
3.6.7 Function parameters................................................................199
3.6.8 Arrow functions........................................................................199
3.7 Evaluation.........................................................................................202
Chapter 4 HTML TABLES- Lazyloading images – JavaScript Objects –
JavaScript Array Functions............................................................................209
4.1 Website Project:...............................................................................209
4.1.1 Project description...................................................................209
4.2 HTML Tables for data presentation..................................................211
4.2.1 HTML Advanced features and accessibility...............................211
4.2.2 Example of zebra striping style for table...................................224
4.3 Lazyloading Images...........................................................................224
4.3.1 Activity......................................................................................225
4.4 JavaScript Objects.............................................................................226
4.4.1 JavaScript objects basics...........................................................228
4.4.2 Objects – Representing data.....................................................234
4.5 JavaScript Array Functions................................................................241
4.5.1 Array filter.................................................................................242
4.5.2 Array map.................................................................................243
4.5.3 Array reduce.............................................................................244
4.6 Assignment.......................................................................................254
Chapter 5 Forms, JavaScript Callback Functions and local storage...........264
5.1 HTML forms......................................................................................264
5.1.1 General accessibility guidance for forms..................................264
5.1.2 Learning about html5 form attributes......................................266
5.1.3 Webforms.................................................................................266
5.2 Callback functions............................................................................274
5.2.1 Callback functions.....................................................................275
5.2.2 Array callback methods & arrow functions...............................276
5.2.3 Activity instructions..................................................................276
5.3 Web storage API-local storage..........................................................277
5.3.1 Activity overview......................................................................283
Chapter 6 Final exam.................................................................................288

Chapter 1 Introduction to JavaScript, Javascript variables


1.1 Hosting on GitHub
1.2 File and folder naming conventions
Overview
When working on the web, there are many things that affect the operation of
the files—the browser, the protocol(s), the operating system, the language(s),
etc. While many of these are out of your control, there are steps you can take
to help keep things consistent and manageable through standard file and
folder naming conventions.

"When you're building a website, you need to assemble these files into a
sensible structure on your local computer, make sure they can talk to one
another, and get all your content looking right before you eventually upload
them to a server." - MDN
1.2.1 Naming Conventions
 Overview
How to name or identify variables in programming is often an organizational
specific preference. This document presents common naming conventions for
variables, functions, and objects in programming.
 Information
 Use as short and as meaningful (semantic) of names as possible. They
are easier to manage and understand. When meaningful, variable
names communicate the purpose of the variable/component.
 Do not use spaces nor special characters in variable names. Use a
naming convention instead.
 Common Naming Conventions
o Camel Case
Each word within a compound word name is capitalized except
for the first word.
julySales, getNewReport()
o Pascal Case
Each word within a compound word name is capitalized.
JulySales, GetNewReport()
o Underscore or Snake Case
Each word within a compound word name is separated by an
underscore.
july_sales, get_new_report()
o Kebab Case
Each word is separated by a hyphen/minus sign.
july-sales, get-new-report()
"Whenever you develop code in a new language, get comfortable with the
variable naming conventions and always check with your team if your
organization ever deviates from the standard. It will make your code more
readable and help your code blend with all of the code commits, pulls and
merges." - TheServerSide.com
Naming conventions for the course
You will be expected to follow these naming conventions throughout the
course.
 Use all lowercase syntax, e.g., products.html
Platforms and systems handle case sensitivity differently. Case sensitivity is an
important concept to understand when managing files and folders.
 Do NOT use spaces in names. Use dashes instead, e.g., design-
document.html
Spaces are interpreted poorly by user agents. Do not use them. The
Hypertext Transfer Protocol (HTTP) ignores spaces, except in file names. In file
names, it replaces a space with a symbol—"%20." This makes URL's look
confusing and can also lend itself to confusion in the mind of site visitors. So
avoid using spaces. Instead, if you have to create a visual space, use
hyphens/dashes.
 Do NOT use special characters, e.g., <,>, \, /, #, ?, !
Special characters often mean specific things to computers, so just avoid
using them completely in the naming of files and folders.
 Use as short and as meaningful (semantic) of names as possible,
e.g., winter-scene-sm.png vs. image13-
v123523brokenbranchlifeimagery w200x200.png
Short, meaningful names save you, other developers, and site visitors from
having to remember long complicated names for files and folders. When
meaningful, they also help predict the purpose or nature of the file or folder
contents when working with those files or folders.
 In this class, the standard folder names for our sites/sub-folders are:
o styles - Folders with this name contain our CSS files.
o images - Folders with this name contain our images.
o scripts - Folders with this name contain our JavaScript files.
1.2.2 Dealing with files
What structure should your website have?
Next, let's look at what structure our test site should have. The most common
things we'll have on any website project we create are an index HTML file and
folders to contain images, style files, and script files. Let's create these now:
1. index.html: This file will generally contain your homepage content, that
is, the text and images that people see when they first go to your site.
Using your text editor, create a new file called index.html and save it
just inside your test-site folder.
2. images folder: This folder will contain all the images that you use on
your site. Create a folder called images, inside your test-site folder.
3. styles folder: This folder will contain the CSS code used to style your
content (for example, setting text and background colors). Create a
folder called styles, inside your test-site folder.
4. scripts folder: This folder will contain all the JavaScript code used to
add interactive functionality to your site (e.g. buttons that load data
when clicked). Create a folder called scripts, inside your test-site folder.
Note: On Windows computers, you might have trouble seeing the file names,
because Windows has an option called Hide extensions for known file
types turned on by default. Generally, you can turn this off by going to
Windows Explorer, selecting the Folder options… option, unchecking
the Hide extensions for known file types check box, then clicking OK. For
more specific information covering your version of Windows, you can search
on the web.
File paths
To make files talk to one another, you have to provide a file path between
them — basically a route, so one file knows where another one is. To
demonstrate this, we will insert a little bit of HTML into our index.html file,
and make it display the image you chose in the article "What will your
website look like?" Alternatively, you can choose an existing image at your
disposal, on your computer or from the Web, and use it in the following
steps:
1. Copy the image you chose earlier into your images folder.
2. Open up your index.html file, and insert the following code into the file
exactly as shown. Don't worry about what it all means for now — we'll
look at the structures in more detail later in the series.
HTMLCopy to Clipboard
<!doctype html>
<html lang="en-US">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>My test page</title>
</head>
<body>
<img src="" alt="My test image" />
</body>
</html>
3. The line <img src="" alt="My test image"> is the HTML code that
inserts an image into the page. We need to tell the HTML where the
image is. The image is inside the images directory, which is in the same
directory as index.html. To walk down the file structure
from index.html to our image, the file path we'd need is images/your-
image-filename. For example, our image is called firefox-icon.png, so
the file path is images/firefox-icon.png.
4. Insert the file path into your HTML code between the double quote
marks of the src="" code.
5. Change the contents of the alt attribute to a description of the
image you are including. In this case, alt="Firefox logo: flaming fox
wrapping the world".
6. Save your HTML file, then load it in your web browser (double-click the
file). You should see your new webpage displaying your image!

Some general rules for file paths:


 To link to a target file in the same directory as the invoking HTML file,
just use the filename, e.g. my-image.jpg.
 To reference a file in a subdirectory, write the directory name in front
of the path, plus a forward slash, e.g. subdirectory/my-image.jpg.
 To link to a target file in the directory above the invoking HTML file,
write two dots. So for example, if index.html was inside a subfolder
of test-site and my-image.jpg was inside test-site, you could
reference my-image.jpg from index.html using ../my-image.jpg.
 You can combine these as much as you like, for
example ../subdirectory/another-subdirectory/my-image.jpg.
For now, this is about all you need to know.
1.3 HTML and CSS review
Grid layout
https://www.youtube.com/watch?v=qm0IfG1GyZU&t=465s

1.4 JavaScript Introduction


What is JavaScript?
https://developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/
What_is_JavaScript
JavaScript is a scripting or programming language that allows you to
implement complex features on web pages — every time a web page does
more than just sit there and display static information for you to look at —
displaying timely content updates, interactive maps, animated 2D/3D
graphics, scrolling video jukeboxes, etc. — you can bet that JavaScript is
probably involved. It is the third layer of the layer cake of standard web
technologies, two of which (HTML and CSS) we have covered in much more
detail in other parts of the Learning Area.
What can it really do?
It can store data or useful values in variables,
It can respond to certain events occurring in the website.
It lets you use APIS.
What are APIS?
APIs are ready-made sets of code building blocks that allow a developer to
implement programs that would otherwise be hard or impossible to
implement. They do the same thing for programming that ready-made
furniture kits do for home building — it is much easier to take ready-cut
panels and screw them together to make a bookshelf than it is to work out
the design yourself, go and find the correct wood, cut all the panels to the
right size and shape, find the correct-sized screws, and then put them
together to make a bookshelf.
They are pieces of code that are useful to add functionality to websites that
otherwise would be impossible.
There two types of APIS: browser APIs and third-party APIs.
Browser APIS Third-Party APIs
Browser APIs are built into your web browser, Third party APIs are not
and are able to expose data from the built into the browser by
surrounding computer environment, or do useful default, and you generally
complex things. For example: have to grab their code
 The DOM (Document Object Model) and information from
API allows you to manipulate HTML and somewhere on the Web.
CSS, creating, removing and changing For example:
HTML, dynamically applying new styles to  The Twitter
your page, etc. Every time you see a popup API allows you to
window appear on a page, or some new do things like
content displayed (as we saw above in our displaying your
simple demo) for example, that's the DOM latest tweets on
in action. your website.
 The Geolocation API retrieves geographical  The Google Maps
information. This is how Google Maps is API and OpenStreet
able to find your location and plot it on a Map API allows you
map. to embed custom
 The Canvas and WebGL APIs allow you to maps into your
create animated 2D and 3D graphics. website, and other
People are doing some amazing things such functionality.
using these web technologies —
see Chrome
Experiments and webglsamples.
 Audio and Video
APIs like HTMLMediaElement and WebRTC
allow you to do really interesting things
with multimedia, such as play audio and
video right in a web page, or grab video
from your web camera and display it on
someone else's computer (try our
simple Snapshot demo to get the idea).

What is JavaScript doing on your page?


A very common use of JavaScript is to dynamically modify HTML and CSS to
update a user interface, via the Document Object Model API (as mentioned
above). Note that the code in your web documents is generally loaded and
executed in the order it appears on the page. Errors may occur if JavaScript is
loaded and run before the HTML and CSS that it is intended to modify. You
will learn ways around this later in the article, in the Script loading
strategies section.
Browser security
Each browser tab has its own separate bucket for running code in (these
buckets are called "execution environments" in technical terms) — this
means that in most cases the code in each tab is run completely separately,
and the code in one tab cannot directly affect the code in another tab — or
on another website. This is a good security measure — if this were not the
case, then pirates could start writing code to steal information from other
websites, and other such bad things.
Note: There are ways to send code and data between different websites/tabs
in a safe manner, but these are advanced techniques that we won't cover in
this course.
JavaScript running order
When the browser encounters a block of JavaScript, it generally runs it in
order, from top to bottom. This means that you need to be careful what order
you put things in. For example, let's return to the block of JavaScript we saw
in our first example:
JSCopy to Clipboard
const button = document.querySelector("button");

button.addEventListener("click", updateName);

function updateName() {
const name = prompt("Enter a new name");
button.textContent = `Player 1: ${name}`;
}
Here we are selecting a button (line 1), then attaching an event listener to it
(line 3) so that when the button is clicked, the updateName() code block
(lines 5–8) is run. The updateName() code block (these types of reusable code
blocks are called "functions") asks the user for a new name, and then inserts
that name into the button text to update the display.
If you swapped the order of the first two lines of code, it would no longer
work — instead, you'd get an error returned in the browser developer
console — Uncaught ReferenceError: Cannot access 'button' before
initialization. This means that the button object has not been initialized yet,
so we can't add an event listener to it.
Note: This is a very common error — you need to be careful that the objects
referenced in your code exist before you try to do stuff to them.
Interpreted versus compiled code
You might hear the terms interpreted and compiled in the context of
programming. In interpreted languages, the code is run from top to bottom
and the result of running the code is immediately returned. You don't have to
transform the code into a different form before the browser runs it. The code
is received in its programmer-friendly text form and processed directly from
that.
Compiled languages on the other hand are transformed (compiled) into
another form before they are run by the computer. For example, C/C++ are
compiled into machine code that is then run by the computer. The program is
executed from a binary format, which was generated from the original
program source code.
JavaScript is a lightweight interpreted programming language. The web
browser receives the JavaScript code in its original text form and runs the
script from that. From a technical standpoint, most modern JavaScript
interpreters actually use a technique called just-in-time compiling to improve
performance; the JavaScript source code gets compiled into a faster, binary
format while the script is being used, so that it can be run as quickly as
possible. However, JavaScript is still considered an interpreted language, since
the compilation is handled at run time, rather than ahead of time.
There are advantages to both types of language, but we won't discuss them
right now.
Server-side versus client-side code
You might also hear the terms server-side and client-side code, especially in
the context of web development. Client-side code is code that is run on the
user's computer — when a web page is viewed, the page's client-side code is
downloaded, then run and displayed by the browser. In this module we are
explicitly talking about client-side JavaScript.
Server-side code on the other hand is run on the server, then its results are
downloaded and displayed in the browser. Examples of popular server-side
web languages include PHP, Python, Ruby, ASP.NET, and even JavaScript!
JavaScript can also be used as a server-side language, for example in the
popular Node.js environment — you can find out more about server-side
JavaScript in our Dynamic Websites – Server-side programming topic.
Dynamic versus static code
The word dynamic is used to describe both client-side JavaScript, and server-
side languages — it refers to the ability to update the display of a web
page/app to show different things in different circumstances, generating new
content as required. Server-side code dynamically generates new content on
the server, e.g. pulling data from a database, whereas client-side JavaScript
dynamically generates new content inside the browser on the client, e.g.
creating a new HTML table, filling it with data requested from the server, then
displaying the table in a web page shown to the user. The meaning is slightly
different in the two contexts, but related, and both approaches (server-side
and client-side) usually work together.
A web page with no dynamically updating content is referred to as static — it
just shows the same content all the time.

How do you add JavaScript to your page?


JavaScript is applied to your HTML page in a similar manner to CSS. Whereas
CSS uses <link> elements to apply external stylesheets and <style> elements
to apply internal stylesheets to HTML, JavaScript only needs one friend in the
world of HTML — the <script> element. Let's learn how this works.
Internal JavaScript
1. First of all, make a local copy of our example file apply-javascript.html.
Save it in a directory somewhere sensible.
2. Open the file in your web browser and in your text editor. You'll see
that the HTML creates a simple web page containing a clickable button.
3. Next, go to your text editor and add the following in your head — just
before your closing </head> tag:
HTML
<script>
// JavaScript goes here
</script>

4. Now we'll add some JavaScript inside our <script> element to make the
page do something more interesting — add the following code just
below the "// JavaScript goes here" line:
JS
document.addEventListener("DOMContentLoaded", () => {
function createParagraph() {
const para = document.createElement("p");
para.textContent = "You clicked the button!";
document.body.appendChild(para);
}

const buttons = document.querySelectorAll("button");

for (const button of buttons) {


button.addEventListener("click", createParagraph);
}
});

5. Save your file and refresh the browser — now you should see that
when you click the button, a new paragraph is generated and placed
below.
EXTERNAL JavaScript
This works great, but what if we wanted to put our JavaScript in an external
file? Let's explore this now.
1. First, create a new file in the same directory as your sample HTML file.
Call it script.js — make sure it has that .js filename extension, as that's
how it is recognized as JavaScript.
2. Replace your current <script> element with the following:
HTML
<script src="script.js" defer></script>

3. Inside script.js, add the following script


JS
function createParagraph() {
const para = document.createElement("p");
para.textContent = "You clicked the button!";
document.body.appendChild(para);
}
const buttons = document.querySelectorAll("button");

for (const button of buttons) {


button.addEventListener("click", createParagraph);
}

4. Save and refresh your browser, and you should see the same thing! It
works just the same, but now we've got our JavaScript in an external
file. This is generally a good thing in terms of organizing your code and
making it reusable across multiple HTML files. Plus, the HTML is easier
to read without huge chunks of script dumped in it.

INLINE JavaScript handlers


Note that sometimes you'll come across bits of actual JavaScript code living
inside HTML. It might look something like this:
JS
function createParagraph() {
const para = document.createElement("p");
para.textContent = "You clicked the button!";
document.body.appendChild(para);
}

HTML
<button onclick="createParagraph()">Click me!</button>

This demo has exactly the same functionality as in the previous two sections,
except that the <button> element includes an inline onclick handler to make
the function run when the button is pressed.
Please don't do this, however. It is bad practice to pollute your HTML with
JavaScript, and it is inefficient — you'd have to include
the onclick="createParagraph()" attribute on every button you want the
JavaScript to apply to.
USING addEventListener INSTEAD
COMMENTS
As with HTML and CSS, it is possible to write comments into your JavaScript
code that will be ignored by the browser, and exist to provide instructions to
your fellow developers on how the code works (and you, if you come back to
your code after six months and can't remember what you did). Comments are
very useful, and you should use them often, particularly for larger
applications. There are two types:
A single line comment is written after a double forward slash (//), e.g.
JS
// I am a comment

A multi-line comment is written between the strings /* and */, e.g


JS
/*
I am also
a comment
*/

So for example, we could annotate our last demo's JavaScript with comments
like so:
JS
// Function: creates a new paragraph and appends it to the bottom of
the HTML body.

function createParagraph() {
const para = document.createElement("p");
para.textContent = "You clicked the button!";
document.body.appendChild(para);
}
/*
1. Get references to all the buttons on the page in an array format.
2. Loop through all the buttons and add a click event listener to each
one.

When any button is pressed, the createParagraph() function will be run.


*/

const buttons = document.querySelectorAll("button");

for (const button of buttons) {


button.addEventListener("click", createParagraph);
}

COMMON MISCONCEPTIONS AND LANGUAGE ISSUES


JavaScript is not the same programming language as the Java programming
language. They are two different languages with different syntax, semantics,
and use cases.
The plural form of "code" in programming is just "code", not "codes".
Example: "Please review my code." or "Please review my program". Not
"Please review my codes."
JavaScript is not just for the browser and client-side scripting. With the
introduction of server-side frameworks like Node.js, JavaScript can now be
used for server-side development as well. JavaScript is a mature language and
has become more powerful and versatile over time.
OPTIONAL RESOURCES
https://www.youtube.com/watch?v=JqCo6XaXTAk
https://www.w3schools.com/js/
https://www.jshero.net/en/home.html
1.5 JavaScript: Variables

Overview
Variables are used to store values. Two kind of values:
Primitive values Objects
Number Function
String Class
Boolean Literal objects
Null

How can these values be used?


They can be used as input to expressions, used in processing, or used in
output to display information.

Prepare
1. Answer the following questions using this resource Storing information
that you need - Variables - MDN Web Docs or through your own
research.
What is the difference between const and let?
For const, the initialization must be at the same time of const declaration.
For variables, they can be declared by using the keyword let first and after to
initialize the variable or both at the same time.
After initializing a constant it is not possible to assign them a new value.
Define the string data type.
This data type is a piece of text.
Which should you use to wrap strings, single quotes('), double quotes("), or
backticks(`)?
It might be used double quotes.
What is a template literal and why is it used to build strings?

VARIABLE EXAMPLE
HTML
<button id="button_A">Press me</button>
<h3 id="heading_A"></h3>

JS
const buttonA = document.querySelector("#button_A");
const headingA = document.querySelector("#heading_A");

buttonA.onclick = () => {
const name = prompt("What is your name?");
alert(`Hello ${name}, nice to see you!`);
headingA.textContent = `Welcome ${name}`;
};

In this example pressing the button runs some code. The first line pops a box
up on the screen that asks the reader to enter their name, and then stores
the value in a variable. The second line displays a welcome message that
includes their name, taken from the variable value and the third line displays
that name on the page.
DECLARING A VARIABLE
Declaring a variable is the process of creating it. To do it the keyword “let”
must be used follow of the name of the variable you want to call your
variable:

JS
let myName;
let myAge;

INITIALIZING A VARIABLE
It is the process of assigning a value to the variable. You do this by typing the
variable name, followed by an equals sign (=), followed by the value you want
to give it. For example:
JS
myName = "Chris";
myAge = 37;

You can declare and initialize a variable at the same time, like this:
JS
let myDog = "Rover";

This is probably what you'll do most of the time, as it is quicker than doing
the two actions on two separate lines.

UPDATING A VARIABLE
Once a variable has been initialized with a value, you can change (or update)
that value by giving it a different value. Try entering the following lines into
your console:
JS
myName = "Bob";
myAge = 40;
AN ASIDE ON VARIABLE NAMING RULES
You can call a variable pretty much anything you like, but there are
limitations. Generally, you should stick to just using Latin characters (0-9, a-z,
A-Z) and the underscore character.
 You shouldn't use other characters because they may cause errors or
be hard to understand for an international audience.
 Don't use underscores at the start of variable names — this is used in
certain JavaScript constructs to mean specific things, so may get
confusing.
 Don't use numbers at the start of variables. This isn't allowed and
causes an error.
 A safe convention to stick to is lower camel case, where you stick
together multiple words, using lower case for the whole first word and
then capitalize subsequent words. We've been using this for our
variable names in the article so far.
 Make variable names intuitive, so they describe the data they contain.
Don't just use single letters/numbers, or big long phrases.
 Variables are case sensitive — so myage is a different variable
from myAge.
 One last point: you also need to avoid using JavaScript reserved words
as your variable names — by this, we mean the words that make up
the actual syntax of JavaScript! So, you can't use words
like var, function, let, and for as variable names. Browsers recognize
them as different code items, and so you'll get errors.
Good name examples Bad name examples
age 1
myAge a
init _12
initialColor myage
finalOutputValue MYAGE
audio1 var
audio2 Document
skjfndskjfnbdskjfb
thisisareallylongvariablenameman

VARIABLE TYPES
Type Explanation Example
Numbers You can store numbers in variables, either whole let myAge = 17;

numbers like 30 (also called integers) or decimal


numbers like 2.456 (also called floats or floating point
numbers). You don't need to declare variable types in
JavaScript, unlike some other programming languages.
When you give a variable a number value, you don't
include quotes:
Strings Strings are pieces of text. When you give a variable a let
dolphinGoodbye =
string value, you need to wrap it in single or double "So long and
quote marks; otherwise, JavaScript tries to interpret it as thanks for all the
fish";
another variable name.
Booleans Booleans are true/false values — they can have two
values, true or false. These are generally used to test a
condition, after which code is run as appropriate. So for
example, a simple case would be: let iAmAlive =
true;
Whereas in reality it would be used more like
this:
let test = 6 < 3;

This is using the "less than" operator (<) to


test whether 6 is less than 3. As you might
expect, it returns false, because 6 is not less
than 3! You will learn a lot more about such
operators later on in the course.
Arrays An array is a single object that contains multiple values
let myNameArray
enclosed in square brackets and separated by commas. = ["Chris", "Bob",
Try entering the following lines into your console: "Jim"];
let
myNumberArray =
[10, 15, 40];

Once these arrays are defined, you can access each


value by their location within the array. Try these lines: myNameArray[0];
// should return
'Chris'
myNumberArray[2
The square brackets specify an index value ]; // should return
40
corresponding to the position of the value you want
returned. You might have noticed that arrays in
JavaScript are zero-indexed: the first element is at index
0.
Objects In programming, an object is a structure of code that
models a real-life object. You can have a simple object
that represents a box and contains information about its
width, length, and height, or you could have an object
that represents a person, and contains data about their
name, height, weight, what language they speak, how to
say hello to them, and more. let dog = { name:
"Spot", breed:
Try entering the following line into your console: "Dalmatian" };

To retrieve the information stored in the object, you can


use the following syntax: dog.name;

DYNAMIC TYPING
So JavaScript is dynamically typed language there is no need to specify the
kind of data the variable will contain (numbers, strings, arrays, etc.).
For example, if you declare a variable and give it a value enclosed in quotes,
the browser treats the variable as a string:
JS
let myString = "Hello";
Even if the value enclosed in quotes is just digits, it is still a string — not a
number — so be careful:
JS
let myNumber = "500"; // oops, this is still a string
typeof myNumber;
myNumber = 500; // much better — now this is a number
typeof myNumber;

CONSTANTS IN JAVASCRIPT
As well as variables, you can declare constants. These are like variables,
except that:
 you must initialize them when you declare them
 you can't assign them a new value after you've initialized them.
For example, using let you can declare a variable without initializing it:
JS
let count;

If you try to do this using const you will see an error:


JS
const count;

Similarly, with let you can initialize a variable, and then assign it a new value
(this is also called reassigning the variable):
JS
let count = 1;
count = 2;

If you try to do this using const you will see an error:


JS
const count = 1;
count = 2;
Note that although a constant in JavaScript must always name the same
value, you can change the content of the value that it names. This isn't a
useful distinction for simple types like numbers or booleans, but consider an
object:
JS
const bird = { species: "Kestrel" };
console.log(bird.species); // "Kestrel"

You can update, add, or remove properties of an object declared using const,
because even though the content of the object has changed, the constant is
still pointing to the same object:
JS
bird.species = "Striated Caracara";
console.log(bird.species); // "Striated Caracara"

WHEN TO USE CONST AND WHEN TO USE LET


If you can't do as much with const as you can with let, why would you prefer
to use it rather than let? In fact const is very useful. If you use const to name
a value, it tells anyone looking at your code that this name will never be
assigned to a different value. Any time they see this name, they will know
what it refers to.
In this course, we adopt the following principle about when to use let and
when to use const:
Use const when you can, and use let when you have to.
This means that if you can initialize a variable when you declare it, and don't
need to reassign it later, make it a constant.
1.6 Template literals (template strings)
JavaScript template literals are string literals allowing embedded expressions.
You can use multi-line strings and string interpolation features with them.
They were called "template strings" in prior editions of the ES2015
specification.
"Template literals are literals delimited with backtick (`) characters, allowing
for multi-line strings, string interpolation with embedded expressions, and
special constructs called tagged templates". - MDN web docs
The following parameters are the basic concepts of template literals:
o Encase the literal in backticks (`).
o Use string text to construct the literal.
o Use JavaScript expressions inserted at a specific location within
the literal using ${expression} notation.
Template literals are sometimes informally called template strings, because
they are used most commonly for string interpolation (to create strings by
doing substitution of placeholders).
SYNTAX
JS
`string text`

`string text line 1


string text line 2`

`string text ${expression} string text`

tagFunction`string text ${expression} string text`

PARAMETERS
string text
The string text that will become part of the template literal. Almost all
characters are allowed literally, including line breaks and other whitespace
characters. However, invalid escape sequences will cause a syntax error,
unless a tag function is used.
expression
An expression to be inserted in the current position, whose value is converted
to a string or passed to tagFunction.
tagFunction
If specified, it will be called with the template strings array and substitution
expressions, and the return value becomes the value of the template literal.
See tagged templates.
DESCRIPTION
Template literals are enclosed by backtick (`) characters instead of double or
single quotes.
Along with having normal strings, template literals can also contain other
parts called placeholders, which are embedded expressions delimited by a
dollar sign and curly braces: ${expression}. The strings and placeholders get
passed to a function — either a default function, or a function you supply.
The default function (when you don't supply your own) just performs string
interpolation to do substitution of the placeholders and then concatenate the
parts into a single string.
To supply a function of your own, precede the template literal with a function
name; the result is called a tagged template. In that case, the template literal
is passed to your tag function, where you can then perform whatever
operations you want on the different parts of the template literal.
To escape a backtick in a template literal, put a backslash (\) before the
backtick.
JS
`\`` === "`"; // true

Dollar signs can be escaped as well to prevent interpolation.


JS
`\${1}` === "${1}"; // true

Multi-line strings
Using normal strings Using template literals
console.log("string text line 1\n" + console.log(`string text line 1
"string text line 2"); string text line 2`);
// "string text line 1 // "string text line 1
// string text line 2" // string text line 2"

String interpolation
Without template literals, when With template literals, you can
you want to combine output from avoid the concatenation operator
expressions with strings, — and improve the readability of
you'd concatenate them using your code — by using placeholders
the addition operator +: of the form ${expression} to
perform substitutions for
embedded expressions:
const a = 5; const a = 5;
const b = 10; const b = 10;
console.log("Fifteen is " + (a + b) + " console.log(`Fifteen is ${a + b} and
and\nnot " + (2 * a + b) + "."); not ${2 * a + b}.`);
// "Fifteen is 15 and // "Fifteen is 15 and
// not 20." // not 20."

That can be hard to read – Note that there's a mild difference


especially when you have multiple between the two syntaxes.
expressions. Template literals coerce their
expressions directly to strings,
while addition coerces its operands
to primitives first. For more
information, see the reference
page for the + operator.
Nesting templates
In certain cases, nesting a template is the easiest (and perhaps more
readable) way to have configurable strings. Within a backtick-delimited
template, it is simple to allow inner backticks by using them inside an $
{expression} placeholder within the template.
without template literals, if you With nesting of template literals,
wanted to return a certain value you can do this:
based on a particular condition,
you could do something like the
following:
let classes = "header"; const classes = `header ${
classes += isLargeScreen() isLargeScreen() ? "" : `icon-$
? "" {item.isCollapsed ? "expander" :
: item.isCollapsed "collapser"}`
? " icon-expander" }`;
: " icon-collapser";

Check your understanding


1. Change this concatenated string into a template literal:
let output = "Welcome to " + courseSubject + " " +
courseNumber + "!Credits: " + courseCredits +
"Length: " + courseLength;
Answer
let output = `Welcome to ${courseSubject} $
{courseNumber}!Credits: ${courseCredits}Length: $
{courseLength}`;
2. Given the following script, finish the code snippet to produce a list of three
temples base on the temples array:
let temples = ["Rome", "Salt Lake", "Nauvoo"];
let listItems = "";
for (const temple of temples) {
listItems += `<li>__________</li>`;
}
document.querySelector("ul").innerHTML = listItems;
Answer
listItems += `<li>${temple}</li>`;
Learing activity: JavaScript variables
HTML
<h1>JavaScript Variables</h1>
<p>First look at the questions 1️⃣-6️⃣ in the JS editor panel. Ponder the
questions about the expressions before looking at the answers and
explanations provided.</p>

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

<details>
<summary>Answer: #1</summary>
<p class="green">❔Why is the result variable value assigned '12' versus
3?</p>
<p>JavaScript performs implicit type coercion when you use the +
operator with different types of values.
In this case, you have a numeric value 1 and a string value '2'. When you
try to concatenate a string with a number using the + operator,
JavaScript converts the number to a string and performs <strong>string
concatenation</strong> and not mathmatical addition.</p>
</details>
<details>
<summary>Answer: #2</summary>
<p class="green">❔What are some other built in functions or methods
that can change a string (sequence of characters) to a number?</p>
<p>The <strong>parseInt()</strong> function parses a string and
returns an integer.</p>
<p>The <strong>parseFloat()</strong> function parses a string and
returns a floating-point number.</p>
<p><strong>Unary plus operator</strong> (+), e.g., <code>result = one;
result += +two; </code>. Using the unary plus operator converts a string
to a number.</p>
<p><strong>Number()</strong> constructur can be used to create a
new Number object, or when called as a function, it converts a string to
a number data type.</p>
</details>
<details>
<summary>Answer: #3</summary>
<p class="green">❔Was the result what you expected?</p>
<p>In this case, the implicit type coercion with the '*' multiplication
operator, the conversion is from a string to a number. So the variable
two with the value of '2' is converted to a number.</p>
</details>
<details>
<summary>Answer: #4</summary>
<p class="green">❔What is the meaning and definition of the acronym
NaN?</p>
<p>"Not a Number". It is a special value that represents the result of an
invalid or undefined mathematical operation. If any operand in an
arithmetic expression is NaN, the result of the entire expression will be
NaN. NaN is not equal to any value, including NaN.</p>
</details>
<details>
<summary>Answer: #5</summary>
<p class="green">❔Did we get the value we expected? Why didn't it
work?</p>
<p>In order to view #5 and #6, you will need to fix the error.
"Assignment to a constant variable" means that a variable declared as a
constant was attempted to be used as the result of an expression
(reassigned a value). You cannot do this with const which makes them
very useful. Solution is to change from const to let on the variables
declaration: <code>let two = '2';</code> on line#3 of the JavaScript.</p>
</details>
<details>
<summary>Answer: #6</summary>
<p class="green">❔Change the array declaration by adding in the
number 4 and place it in its correct acscending order position.</p>
<p>const myArray = [1,2,3,4,5];</p>
</details>
CSS
body {margin: 1rem;}
h1 {border-bottom: 1px solid #bbb;}
p {margin:0;font-family: courier;}
details {
margin: 1rem 2rem;
border: 1px solid rgba(0,0,0,.1);
padding: 0.5rem;
color: #000;
background-color:rgba(238, 254, 238, 1); ;
}
details p {margin: 0.5rem 0 0 0.5rem;}
.green {color: #008000;}

JS
// Declare and Instantiate Variables of different types and then add them
together using the + operator.
const one = 1;
let two = '2';
let result = one + two;
output("#1", result); // 💡output function defined below
// ❔1️⃣: Why is the result variable value assigned '12' versus 3?

// Using built-in JS functions, change variable data types


result = one + parseInt(two);
output("#2", result);
// ❔2️⃣: Note the output. What are some other built in functions or
methods that can change a string (sequence of characters) to a number?

// What about multiplication?


result = one * two;
output("#3", result);
// ❔3️⃣: Was the result what you expected?

// A new variable is declared and assigned an alpha character and added


to the varaible identified as one.
const three = "e";
result = one * three;
output("#4", result);
// ❔4️⃣: What is the meaning and definition of the acronym NaN?

// Let's try changing the value of the variable two.


two = 4;
result = one + two;
output("#5", result);
// ❔5️⃣: Did we get the value we expected? Why didn't it work?
// Turn on the console panel (bottom left of screen) in order to view the
error. Fix the error by changing how the variable two was declared.

// Let's declare an array and initialize it with 4 values


const myArray = [1,2,3,4,5];
result = myArray;
output("#6", result);
// ❔6️⃣: Change the array to by adding in the number 4 in its correct
ascending order position.

// ***************************************
// The function output defined below is used to aid in displaying the
results by appending the output paragraph with an id attribute of
'output'
function output(linenumber, content) {
const outputElement = document.querySelector('#output');
outputElement.innerHTML += `<p><strong>${linenumber}</strong>: $
{content}</p>`;
}
Answer: #1
Why is the result variable value assigned '12' versus 3?
JavaScript performs implicit type coercion when you use the + operator with
different types of values. In this case, you have a numeric value 1 and a string
value '2'. When you try to concatenate a string with a number using the +
operator, JavaScript converts the number to a string and performs string
concatenation and not mathmatical addition.

Answer: #2
❔What are some other built in functions or methods that can change a string
(sequence of characters) to a number?
The parseInt() function parses a string and returns an integer.
The parseFloat() function parses a string and returns a floating-point number.
Unary plus operator (+), e.g., result = one; result += +two; . Using the unary
plus operator converts a string to a number.
Number() constructur can be used to create a new Number object, or when
called as a function, it converts a string to a number data type.
Answer: #3
❔Was the result what you expected?
In this case, the implicit type coercion with the '*' multiplication operator, the
conversion is from a string to a number. So the variable two with the value of
'2' is converted to a number.
Answer: #4
❔What is the meaning and definition of the acronym NaN?
"Not a Number". It is a special value that represents the result of an invalid or
undefined mathematical operation. If any operand in an arithmetic
expression is NaN, the result of the entire expression will be NaN. NaN is not
equal to any value, including NaN.
Answer: #5
❔Did we get the value we expected? Why didn't it work?
In order to view #5 and #6, you will need to fix the error. "Assignment to a
constant variable" means that a variable declared as a constant was
attempted to be used as the result of an expression (reassigned a value). You
cannot do this with const which makes them very useful. Solution is to
change from const to let on the variables declaration: let two = '2'; on line#3
of the JavaScript.

Answer: #6
❔Change the array declaration by adding in the number 4 and place it in its
correct acscending order position.
const myArray = [1,2,3,4,5];
1.7 Adding last modification and prorated year

Adding the current year


the copyright year (the current year) in the footer's first paragraph, and
Note this CodePen summary of using the Date object in different ways.
HTML
<p>&copy;<span id="currentyear"></span> | Carlos Medina |
Bolivia</p>

JS
const today = new Date();
currentyear.innerHTML = `<span>${today.getFullYear()}</span>`;

Adding the last modification date


Use the lastModified property of the document object to get this date/time
dynamically.

HTML
<p>Last Modification: <span id="lastModified"></span></p>

JS
let oLastModif = new Date(document.lastModified);
lastModified.innerHTML= `<span>${oLastModif}</span>`;

https://developer.mozilla.org/en-US/docs/Web/API/Document/lastModified
1.8 Navigation Menu example
HTML
<header>
<h1>Heading in Header</h1>
</header>
<nav>
<ul>
<li><a href="#" class="active">Home</a></li>
<li><a href="#">Sandbox</a></li>
<li><a href="#">References</a></li>
<li><a href="#">Term Project</a></li>
<li><a href="#">About</a></li>
</ul>
</nav>

CSS
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
font-family: "Sansita", sans-serif;
}

/* mobile **************************/
header {
background-color: #bbb;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
border: 1px solid rgba(0, 0, 0, 0.1);
}

header,
main {
margin: 0 auto;
}

h1 {
font-size: 2rem;
}

nav {
background-color: #36454f;
margin: 0 auto;
max-width: 800px;
}
nav ul {
list-style-type: none;
}
nav a {
display: block;
color: #fff;
text-align: center;
padding: 1rem;
text-decoration: none;
}

nav a:hover {
text-decoration:overline;
}

.active {
color: yellow;
}

/* Larger Views ******************************/


@media (min-width: 640px) {
nav ul {
display: flex;
}
nav ul li {
flex: 1 1 100%;
}
}

Result
Chapter 2 CSS media queries, JavaScript Constructs, The
Document Object Model (DOM) interface, Handling DOM
effects, Responsive Menus, JavaScript debugging

2.1 CCS media queries

OverView
CSS Media Queries help web designers/developers show different styles for
the content on various screen sizes. Designers use these queries to decide
when to change the design or layout based on the content and set
breakpoints, like the minimum screen width.
"Do NOT define breakpoints based on device classes. Defining breakpoints
based on specific devices, products, brand names, or operating systems that
are in use today can result in a maintenance nightmare. Instead, the content
itself should determine how the layout adjusts to its container."
- How to choose breakpoints - Responsive Web - Google Web Fundamentals
2.1.1 Prepare
CSS media queries are essential to responsive web design. The @media at-
rule specifies condition(s) to create a block of CSS rules that are applied if the
condition(s) evaluates to true. This is extremely useful as selected elements
can be repositioned, resized, hidden, exposed, etc. based upon the user's
viewport size.
Here is the general syntax is setting up a CSS media query:
@media not|only mediatype and (expressions) {
/*CSS rules go here inside the @media query’s opening and closing
curly brackets {}*/
}

Here is an example CSS media query which could be embedded in a CSS file
or be the entire contents of a CSS file if wanted. This example only has one
CSS rule.
@media screen and (min-width: 640px) {
h1{
font-size: 2.5 rem;
margin: 1 rem;
color: navy;
}
}

Sample code explanation


1️⃣ The @media screen and (min-width: 640px) {is the signature line of
the @media query block of CSS rules to be applied if the conditions are
met. In this case the conditions are if the media type is a screen and the
viewport minimum width is at least 640 pixels wide.
2️⃣ The h1 {is a heading 1 (<h1>) element selector which starts the
defined CSS rule.
3️⃣-5️⃣ The @font-size: 2.5rem; margin: 1rem; color:
navy; are declarations to be applied to any <h1> elements if the
@media query conditions are met.
6️⃣ The first }closes the CSS rule for <h1> code elements.
7️⃣ The last }closes the media query.

Note that curly brackets { } are used to contain a specific media query and are
also used to define CSS Rules. Be sure to keep track of your bracket scope
(start and end). Using automatic VS Code Format Document features will help
you recognize issues with your structure.
Media query application demonstration
https://video.byui.edu/media/t/0_oacos9ak

Design considerations: The viewport


https://www.youtube.com/watch?v=QY3lTBZnJmE&t=10s
2.1.2 Activity instructions

For this activity, you will create a simple HTML page with two CSS files. The
first CSS file will be used to style the page for mobile devices. The second CSS
file will be used to style the page for larger viewports. You will use CSS media
queries to apply the appropriate CSS file based upon the viewport width.
Remember that a responsible use of an ♾️AI generative tool could be to ask
questions about how to formulate a specific code piece. For example, "how to
combine selectors in CSS", and an example will be given with which you can
apply to your own code. Do not spin your tires in the mud so that you do not
get stuck on a single requirement in the activity.
1. File and Folder Setup
Add a new HTML file named "media-query.html" in a "week02" named
folder all within your same wdd131 repo.
Add two CSS files named "media-query.css" and "media-query-
large.css" to an appropriate subfolder ("styles") within
the week02 folder.
2. HTML
In your media-query.html file, create a valid HTML page with
standard head content including
o Meta Charset Attribute
o Meta Viewport Element
o Title Element
o Meta Description Element
o Meta Author Element
o Link to a Google Font named "Roboto" - regular 400.
o Link references to your CSS two (2) files. Link the media-
query.css file first.
Example
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WDD 131 - Media Query Example</title>
<meta name="description" content="Media query learning activity example
page.">
<meta name="author" content="[Put your full name here]">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?
family=Roboto&display=swap" rel="stylesheet">
<link rel="stylesheet" href="styles/media-query.css">
<link rel="stylesheet" href="styles/media-query-large.css">
</head>
In the body of the HTML document, add a header with an h1,
a main element with two section elements, and a footer element.
The h1 element should contain the words "Media Query Example".
Each section h2 heading contains a scripture with book, chapter, and verse.
The section paragraph contains a copy of the actual scripture referenced in
the heading.
The footer should contain your name.
Example
<header>
<h1>Media Query Example</h1>
</header>
<main>
<section>
<h2>2 Nephi 32:9</h2>
<p>But behold, I say unto you that ye must pray always, and not faint; that
ye must not perform any thing unto the Lord save in the first place ye shall
pray unto the Father in the name of Christ, that he will consecrate thy
performance unto thee, that thy performance may be for the welfare of thy
soul.</p>
</section>
<section>
<h2>Helaman 12:24</h2>
<p>And may God grant, in his great fulness, that men might be brought
unto repentance and good works, that they might be restored unto grace for
grace, according to their works.</p>
</section>
</main>
<footer>
[Your Full Name Here]
</footer>
3. CSS
1. Style the document as shown in the example screenshots given below.
1. media-query.css
1. Do not include a media query.
2. Use the Google Font - Roboto in the body rule.
3. The header, main, and footer each
1. have a maximum width of 640 pixels,
2. are centered on the page using margin: 1rem auto,
3. include a faint border,
4. use appropriate padding, and
5. have a blueish background color of your choice.
Remember that you can combine these three selectors into one rule or create
a class that contains these common CSS declarations.
4. Declare the main element to be a CSS grid with a grid
template of only one column, and a equal gap of 1rem,
and
If you had a question to pose to the class in Microsoft Teams, use specific and
descriptive language, e.g., "I have a question about the media-query
assignment part 5.1.4. I do not know how to set the main element grid to only
one column with an even gap of 1rem."
5. Declare the section elements to also have padding and a
lighter or white background.
Check Your Understanding
body {
font-family: 'Roboto', sans-serif;
}

header, main, footer {


max-width: 640px;
margin: 1rem auto;
border: 1px solid #bbb;
padding: 1rem;
background-color: #e6f2ff;
}

main {
display: grid;
grid-template-columns: 1fr;
grid-gap: 1rem;
}

section {
padding: 1rem;
background-color: #fff;
}
2. In the media-query-large.css,
1. Write a containing media query to be applied at a viewport
width of 500px or greater.
@media screen and (min-width: 500px)
2. Change through declaration within the media query
the header to a black background with white text, and
3. Change the main element to display two columns of equal
size.Example
grid-template-columns: 1fr 1fr;
Example Screenshots
Figure 1: Mobile View Screenshot

Fig
ure 2: Wider View Screenshot
Testing
You should be continuously checking your browser rendered work using Live
Server extension.
1. Test your work by resizing your browser window or by using DevTools
device settings to see the changes in the layout.
2. Run through this Google CodeLab to test color contrast accessibility or
use the CSS Overview to get a quick check on color contrast and other
CSS usage.
3. You will need to commit and push your work to your GitHub Pages
enabled wdd131 site in order to use the Page Audit Tool.

2.2 JavaScript Construtcs


Overview
Through the prerequisite programming course requirements for this course,
you have established a foundational understanding of the common,
programming building blocks or constructs including operators, expressions,
decision structures, looping, and functions. This activity focuses on a few of
the common control structures in programming.
2.2.1 Common controls structures or building
blocks in JavaScript
2.2.1.1 Conditional statements
if statement: executes a block of code if a specified condition is true.

if (condition) {
// Code to execute if the condition is true
}

The condition is evaluated to a boolean value, i.e., true or false. Writing


condition statements is a critical skill in programming. The use
of operators and expressions is a key concept in writing condition
statements that solve programming problems.
else statement: Provides an alternative block of code to execute if the
condition in the if statement is false.

if (condition) {
// Code to execute if the condition is true
} else {
// Code to execute if the condition is false
}

else if statement: This structure allows for the checking of multiple conditions
in sequence.

if (condition1) {
// Code to execute if condition1 is true
} else if (condition2) {
// Code to execute if condition2 is true
} else {
// Code to execute if none of the conditions are true
}

Switch statements: Provides a way to execute selective blocks of code based


on the value of an expression.

switch (expression) {
case value1:
// Code to execute if expression is equal to value1
break;
case value2:
// Code to execute if expression is equal to value2
break;
// ... more cases ...
default:
// Code to execute if none of the cases match
}
Looping statements:
for Loop: Repeats a block of code a specified number of times.

for (let i = 0; i < 19; i++) {


// Code to execute in each iteration
}

while Loop: Repeats a block of code as long as a specified condition is true.

while (condition) {
// Code to execute while the condition is true
}

forEach Loop: This loop structure is for arrays. It iterates over each element
of the array.

array.forEach(function(element) {
// Code to execute for each element
});

2.2.1.2 JavaScript Operators


What are operators?
In programming, operators are special symbols (characters) that are used to
perform operations on operands (variables and values) and to process
expressions. Most operators are used to perform mathematical operations
such as addition, subtraction, multiplication, etc. However, there are other
operators that are used to perform other operations such as assignment,
comparison, logical, string, conditional, etc.
Types of operators
 Assignment - used to assign values to variables. Tutorial
 Arithmetic - used to preform arithmetic. Tutorial
 Comparison - Tutorial
 Logical - important to create compound conditions as they determine
the logic between expressions/values.
 Conditional (ternary) - alternative to if...else statement. Reference
 Spread (...) - this was used in the task last week. Reference
References
1. Reference JavaScript Operators Reference - w3schools.com
2. Reference More depth reference on Expressions and Operators
2.2.1.2.1JavaScript Assignment
Assignment operators
Assignment operators assign values to JavaScript variables.

Operator Example Same As

= x=y x=y

+= x += y x=x+y

-= x -= y x=x-y

*= x *= y x=x*y

/= x /= y x=x/y

%= x %= y x=x%y

**= x **= y x = x ** y
Shift assignment operators

Operator Example Same As

<<= x <<= y x = x << y

>>= x >>= y x = x >> y

>>>= x >>>= y x = x >>> y

Bitwise Assignment Operators

Operator Example Same As

&= x &= y x=x&y

^= x ^= y x=x^y

|= x |= y x=x|y

Logical assignment operators

Operator Example Same As

&&= x &&= y x = x && (x = y)

||= x ||= y x = x || (x = y)

??= x ??= y x = x ?? (x = y)
Operator What it does Examples
= The Simple Assignment let x = 10;
let x = 10 + y;
Operator assigns a
value to a variable.
+= The Addition let x = 10;
x += 5;
Assignment
Operator adds a value
to a variable.
-= The Subtraction let x = 10;
x -= 5;
Assignment
Operator subtracts a
value from a variable.
*= The Multiplication let x = 10;
x *= 5;
Assignment
Operator multiplies a
variable.
**= The Exponentiation let x = 10;
x **= 5;
Assignment
Operator raises a
variable to the power
of the operand.
/= The Division let x = 10;
x /= 5;
Assignment
Operator divides a
variable.
%= The Remainder let x = 10;
x %= 5;
Assignment
Operator assigns a
remainder to a variable.
<<= The Left Shift let x = -100;
x <<= 5;
Assignment
Operator left shifts a
variable.
>>= The Right Shift let x = -100;
x >>= 5;
Assignment
Operator right shifts a
variable (signed).
>>>= The Unsigned Right let x = -100;
x >>>= 5;
Shift Assignment
Operator right shifts a
variable (unsigned).
&= The Bitwise AND
let x = 10;
Assignment x &= 5;
Operator does a
bitwise AND operation
on two operands and
assigns the result to the
the variable.
|= The Bitwise OR let x = 10;
x |= 5;
Assignment
Operator does a
bitwise OR operation
on two operands and
assigns the result to the
variable.
^= The Bitwise XOR let x = 10;
x ^= 5;
Assignment
Operator does a
bitwise XOR operation
on two operands and
assigns the result to the
variable.
&&= The Logical AND let x = 10;
x &&= 5;
assignment operator is
used between two
values.
If the first value is true,
the second value is
assigned.

||= The Logical OR let x = 10;


x ||= 5;
assignment operator is
used between two
values.
If the first value is false,
the second value is
assigned.

??= The Nullish coalescing let x;


x ??= 5;
assignment operator is
used between two
values.
If the first value is
undefined or null, the
second value is
assigned.

2.2.1.2.2JAVASCRIPT COMPARISON AND LOGICAL


OPERATORS
Comparison operators
Comparison operators are used in logical statements to determine equality or
difference between variables or values.
Given that x = 5, the table below explains the comparison operators:

Operator Description Comparing Returns

== equal to x == 8 false

x == 5 true

x == "5" true

=== equal value and equal type x === 5 true

x === "5" false


!= not equal x != 8 true

!== not equal value or not equal type x !== 5 false

x !== "5" true

x !== 8 true

> greater than x>8 false

< less than x<8 true

>= greater than or equal to x >= 8 false

<= less than or equal to x <= 8 true

Logical operators
Logical operators are used to determine the logic between variables or
values.
Given that x = 6 and y = 3, the table below explains the logical operators:

Operator Description Example

&& and (x < 10 && y > 1) is true

|| or (x == 5 || y == 5) is false

! not !(x == y) is true

Conditional (ternary) operator


JavaScript also contains a conditional operator that assigns a value to a
variable based on some condition.
Syntax
variablename = (condition) ? value1:value2
Example
let voteable = (age < 18) ? "Too young":"Old enough";
If the variable age is a value below 18, the value of the
variable voteable will be "Too young", otherwise the value of
voteable will be "Old enough".

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
Operators/Conditional_operator
The conditional (ternary) operator is the only JavaScript operator that takes
three operands: a condition followed by a question mark (?), then an
expression to execute if the condition is truthy followed by a colon (:), and
finally the expression to execute if the condition is falsy. This operator is
frequently used as an alternative to an if...else statement.
Syntax
condition ? exprIfTrue : exprIfFalse
Parameters
condition
An expression whose value is used as a condition.
exprIfTrue
An expression which is executed if the condition evaluates to a truthy value
(one which equals or can be converted to true).
exprIfFalse
An expression which is executed if the condition is falsy (that is, has a value
which can be converted to false).
Description
Besides false, possible falsy expressions are: null, NaN, 0, the empty string
(""), and undefined. If condition is any of these, the result of the conditional
expression will be the result of executing the expression exprIfFalse.
Examples:
const age = 26;
const beverage = age >= 21 ? "Beer" : "Juice";
console.log(beverage); // "Beer"

Handling null values


One common usage is to handle a value that may be null:
const greeting = (person) => {
const name = person ? person.name : "stranger";
return `Howdy, ${name}`;
};

console.log(greeting({ name: "Alice" })); // "Howdy, Alice"


console.log(greeting(null)); // "Howdy, stranger"

Conditional chains
The ternary operator is right-associative, which means it can be "chained" in
the following way, similar to an if … else if … else if … else chain:
function example() {
return condition1 ? value1
: condition2 ? value2
: condition3 ? value3
: value4;
}

This is equivalent to the following if..else chain.


function example() {
if (condition1) {
return value1;
} else if (condition2) {
return value2;
} else if (condition3) {
return value3;
} else {
return value4;
}
}
Comparing different types
Comparing data of different types may give unexpected results.
When comparing a string with a number, JavaScript will convert the string to
a number when doing the comparison. An empty string converts to 0. A non-
numeric string converts to NaN which is always false.

Case Value

2 < 12 true

2 < "12" true

2 < "John" false

2 > "John" false

2 == "John" false

"2" < "12" false

"2" > "12" true

"2" == "12" false

When comparing two strings, "2" will be greater than "12", because
(alphabetically) 1 is less than 2.
To secure a proper result, variables should be converted to the proper type
before comparison:
Activity instructions
1. Ponder: Repetition Structures
2.2.2 Loops and iteration
Overview
Repeating code is a common task in programming. JavaScript provides several
ways to repeat code including for, while, do...while, and for...in statements.
Each of these statements has a specific use case and syntax. forEach is a
method that can be used on arrays to iterate over each item in the array.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/
Loops_and_iteration
What are the statements for loops provide in JavaScript?
R. – They are:
for statement
do… while statement
while statement
labeled statement
break statement
continue statement
for… in statement
for… of statement

What are the different ways to determine the start and end point of the loop
that the various loop mechanisms offer?
What are the situations that different types of loops performs best?
Type of loop Loop mechanism (Way to Best use for
determine the start and
end point of the loop)
for loop The initializing
expression initialization, if
for (initialization; any, is executed. This
condition; expression usually
afterthought) initializes one or more
statement loop counters, but the
syntax allows an
expression of any degree
of complexity. This
expression can also
declare variables.

The condition expression


is evaluated. If the value
of condition is true, the
loop statements execute.
Otherwise, the for loop
terminates. (If
the condition expression
is omitted entirely, the
condition is assumed to
be true.)

do… while The do...while statement


do repeats until a specified
statement condition evaluates to
while (condition); false.

statement is always
executed once before the
condition is checked. (To
execute multiple
statements, use a block
statement ({ }) to group
those statements.)
If condition is true, the
statement executes again.
At the end of every
execution, the condition is
checked. When the
condition is false,
execution stops, and
control passes to the
statement
following do...while.

while The condition test while is great for


while (condition) occurs before statement i
statement
when you need to do
n the loop is executed. If something until a
the condition certain state occurs in
returns true, statement is your program. You
executed and know when you want
the condition is tested
the loop to end...but
again. If the condition
aren't sure how many
returns false, execution
stops, and control is loops it will require to
passed to the statement get there.
following while.
for statement

Expression of any degree of complexity. Variables can be declared also. If the value of condition is true the loop executes, otherwise it te

1 2 4
for (initialization; condition; afterthought)
statement3
To execute multiple statements use a block statement ({}) to group those statements.

1. The initializing expression initialization, if any, is executed. This


expression usually initializes one or more loop counters, but the syntax
allows an expression of any degree of complexity. This expression can
also declare variables.
2. The condition expression is evaluated. If the value of condition is true,
the loop statements execute. Otherwise, the for loop terminates. (If
the condition expression is omitted entirely, the condition is assumed
to be true.)
3. The statement executes. To execute multiple statements, use a block
statement ({ }) to group those statements.
4. If present, the update expression afterthought is executed.
5. Control returns to Step 2.
Example

HTML
<form name="selectForm">
<label for="musicTypes"
>Choose some music types, then click the button below:</label
>
<select id="musicTypes" name="musicTypes" multiple>
<option selected>R&B</option>
<option>Jazz</option>
<option>Blues</option>
<option>New Age</option>
<option>Classical</option>
<option>Opera</option>
</select>
<button id="btn" type="button">How many are selected?</button>
</form>
JS
function countSelected(selectObject) {
let numberSelected = 0;
for (let i = 0; i < selectObject.options.length; i++) {
if (selectObject.options[i].selected) {
numberSelected++;
}
}
return numberSelected;
}

const btn = document.getElementById("btn");

btn.addEventListener("click", () => {
const musicTypes = document.selectForm.musicTypes;
console.log(`You have selected ${countSelected(musicTypes)} option(s).`);
});

do… while statement

It executes once before the condition is checked. To execute multiple statements, use a block statement ({}) to group statements
If condition is true
If condition is true, the statement executes again. At the end of every execu

do 3
1 statement
2 while (condition);

If condition is not true


3

statement is always executed once before the condition is checked. (To


execute multiple statements, use a block statement ({ }) to group those
statements.)
If condition is true, the statement executes again. At the end of every
execution, the condition is checked. When the condition is false, execution
stops, and control passes to the statement following do...while.

Example
JS
let i = 0;
do {
i += 1;
console.log(i);
} while (i < 5);

while statement
A while statement executes its statements as long as a specified condition
evaluates to true. A while statement looks as follows:

The condition test occurs before statement in the loop is executed. If the condition returns true, statement is executed, and the condition is test

1
while (condition)
statement 2

It is executed as long as a specified condition evaluates to true. To execute multiple statement, use a block statement ({})

If the condition becomes false, statement within the loop stops executing and
control passes to the statement following the loop.
The condition test occurs before statement in the loop is executed. If the
condition returns true, statement is executed and the condition is tested
again. If the condition returns false, execution stops, and control is passed to
the statement following while.
To execute multiple statements, use a block statement ({ }) to group those
statements.
Example 1
The following while loop iterates as long as n is less than 3:
JS
let n = 0;
let x = 0;
while (n < 3) {
n++;
x += n;
}

With each iteration, the loop increments n and adds that value to x.
Therefore, x and n take on the following values:
 After the first pass: n = 1 and x = 1
 After the second pass: n = 2 and x = 3
 After the third pass: n = 3 and x = 6
After completing the third pass, the condition n < 3 is no longer true, so the
loop terminates.
Example 2
Avoid infinite loops. Make sure the condition in a loop eventually
becomes false—otherwise, the loop will never terminate! The statements in
the following while loop execute forever because the condition never
becomes false:
JS
// Infinite loops are bad!
while (true) {
console.log("Hello, world!");
}
labeled statement
A label provides a statement with an identifier that lets you refer to it
elsewhere in your program. For example, you can use a label to identify a
loop, and then use the break or continue statements to indicate whether a
program should interrupt the loop or continue its execution.
The syntax of the labeled statement looks like the following:
JS
label:
statement

The value of label may be any JavaScript identifier that is not a reserved
word. The statement that you identify with a label may be any statement. For
examples of using labeled statements, see the examples
of break and continue below.
break statement
Use the break statement to terminate a loop, switch, or in conjunction with a
labeled statement.
 When you use break without a label, it terminates the innermost
enclosing while, do-while, for, or switch immediately and transfers
control to the following statement.
 When you use break with a label, it terminates the specified labeled
statement.
The syntax of the break statement looks like this:
JS
break;
break label;
1. The first form of the syntax terminates the innermost enclosing loop
or switch.
2. The second form of the syntax terminates the specified enclosing
labeled statement.
Example 1
The following example iterates through the elements in an array until it finds
the index of an element whose value is theValue:
JS
for (let i = 0; i < a.length; i++) {
if (a[i] === theValue) {
break;
}
}

Example 2: Breakin to a label


JS
let x = 0;
let z = 0;
labelCancelLoops: while (true) {
console.log("Outer loops:", x);
x += 1;
z = 1;
while (true) {
console.log("Inner loops:", z);
z += 1;
if (z === 10 && x === 10) {
break labelCancelLoops;
} else if (z === 10) {
break;
}
}
}
continue statement
The continue statement can be used to restart a while, do-while, for,
or label statement.
 When you use continue without a label, it terminates the current
iteration of the innermost enclosing while, do-while, or for statement
and continues execution of the loop with the next iteration. In contrast
to the break statement, continue does not terminate the execution of
the loop entirely. In a while loop, it jumps back to the condition. In
a for loop, it jumps to the increment-expression.
 When you use continue with a label, it applies to the looping statement
identified with that label.
The syntax of the continue statement looks like the following:
JS
continue;
continue label;

Example 1
The following example shows a while loop with a continue statement that
executes when the value of i is 3. Thus, n takes on the values 1, 3, 7, and 12.
JS
let i = 0;
let n = 0;
while (i < 5) {
i++;
if (i === 3) {
continue;
}
n += i;
console.log(n);
}
// Logs:
// 1 3 7 12
If you comment out the continue;, the loop would run till the end and you
would see 1,3,6,10,15.
Example 2
A statement labeled checkiandj contains a statement labeled checkj.
If continue is encountered, the program terminates the current iteration
of checkj and begins the next iteration. Each time continue is
encountered, checkj reiterates until its condition returns false. When false is
returned, the remainder of the checkiandj statement is completed,
and checkiandj reiterates until its condition returns false. When false is
returned, the program continues at the statement following checkiandj.
If continue had a label of checkiandj, the program would continue at the top
of the checkiandj statement.
JS
let i = 0;
let j = 10;
checkiandj: while (i < 4) {
console.log(i);
i += 1;
checkj: while (j > 4) {
console.log(j);
j -= 1;
if (j % 2 === 0) {
continue checkj;
}
console.log(j, "is odd.");
}
console.log("i =", i);
console.log("j =", j);
}

for…in statement
The for...in statement iterates a specified variable over all the enumerable
properties of an object. For each distinct property, JavaScript executes the
specified statements. A for...in statement looks as follows:

JS
for (variable in object)
statement

Example
The following function takes as its argument an object and the object's name.
It then iterates over all the object's properties and returns a string that lists
the property names and their values.
JS
function dumpProps(obj, objName) {
let result = "";
for (const i in obj) {
result += `${objName}.${i} = ${obj[i]}<br>`;
}
result += "<hr>";
return result;
}

For an object car with properties make and model, result would be:
car.make = Ford
car.model = Mustang

Arrays
Although it may be tempting to use this as a way to iterate
over Array elements, the for...in statement will return the name of your user-
defined properties in addition to the numeric indexes.
Therefore, it is better to use a traditional for loop with a numeric index when
iterating over arrays, because the for...in statement iterates over user-defined
properties in addition to the array elements, if you modify the Array object
(such as adding custom properties or methods).
for…of statement
The for...of statement creates a loop Iterating over iterable
objects (including Array, Map, Set, arguments object and so on), invoking a
custom iteration hook with statements to be executed for the value of each
distinct property.
JS
for (variable of object)
statement

The following example shows the difference between a for...of loop and
a for...in loop. While for...in iterates over property names, for...of iterates over
property values:
JS
const arr = [3, 5, 7];
arr.foo = "hello";

for (const i in arr) {


console.log(i);
}
// "0" "1" "2" "foo"

for (const i of arr) {


console.log(i);
}
// Logs: 3 5 7

The for...of and for...in statements can also be used with destructuring. For
example, you can simultaneously loop over the keys and values of an object
using Object.entries().
JS
const obj = { foo: 1, bar: 2 };

for (const [key, val] of Object.entries(obj)) {


console.log(key, val);
}
// "foo" 1
// "bar" 2
2.2.3 Examples
1. Activities to complete
https://byui-cit.github.io/learning-modules/modules/js/loops/ponder1/
for-of #
Replacement for the for loop. Array.forEach or Array.map are usually better
options if you are looping over an array (which you often are).
for-in #
This allows you to iterate over objects. It returns the key of the item instead
of the value like for of. If you find yourself reaching for this often you should
probably take a look at how you are storing your data...
while #
while is great for when you need to do something until a certain state occurs
in your program. You know when you want the loop to end...but aren't sure
how many loops it will require to get there.

2. Given the following variable declarations:


const DAYS = 6;
const LIMIT = 30;
let studentReport = [11, 42, 33, 64, 29, 37, 44];

 Write a for loop that will iterate through the studentReport array and
print to the console the current array value if it is below 30.
 Repeat the previous programming snippet by using a while loop.
 Repeat the previous programming snippet by using a forEach loop.
 Repeat the previous programming snippet by using a for...in loop.
 Use any type of repetition (looping) statement to dynamically produce
the day names (Monday, Tuesday, Wednesday, etc.) of the next number
of DAYS from today's date.
for ()
Answer

// for loop
for (let i = 0; i < studentReport.length; i++) {
if (studentReport[i] < LIMIT) {
console.log(studentReport[i]);
}
}

Initialization: a variable that represents to the


position of the values in the array.
Afterthought: increases a unit to pass to the next
position of the array.
Condition: that i < to the number of elements in that
array.
studentReport[i] invoques the value of the position
equals to i.

// while loop
let i = 0;
while (i < studentReport.length) {
if (studentReport[i] < LIMIT) {
console.log(studentReport[i]);
}
i++;
}

// forEach loop
studentReport.forEach(function (item) {
if (item < LIMIT) {
console.log(item);
}
});

// for...in loop
for (let i in studentReport) {
if (studentReport[i] < LIMIT) {
console.log(studentReport[i]);
}
}
The length data property of an array instance represents the number of
elements in that array.
Use this CodePen to guide you in a solution to the last question. This requires
you to sift through the example code to find what is applicable.
Get future days from today example
https://codepen.io/blazzard-jason/pen/wLmeXj
HTML
<h1>📆 Next 6 Days of the Week</h1>
<p id="today"></p>
<h2>Future Days of the Week</h2>
<ul></ul>

CSS
body {
margin: .5rem auto;
padding: 0;
width: 500px;
}

h1 {text-align:center;}
p{
background-color: #eee;
border: 1px solid #999;
padding: .35rem;

}
JS
const n = 6; // number of days forward
// get output location on document to append within list
const output = document.getElementsByTagName("ul");
// Intl.DateTimeFormat Options
const options = { weekday: 'long'}; // vs. short, etc.

// BEGIN
const today = new Date();
// TODAY test output
let todaystring = new Intl.DateTimeFormat('en-US',
options).format(today);
document.getElementById('today').innerHTML = `Today is $
{todaystring}. `;

// next n days
for (let i = 1; i <= n; i++ ) {
let nextday = new Date();
nextday.setDate(today.getDate() + i);
let nextdaystring = new Intl.DateTimeFormat('en-US',
options).format(nextday);
item = document.createElement("li"); // list item
item.textContent = nextdaystring;
output[0].appendChild(item);
}
Output

REFERENCES
https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/
conditionals
https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/
Looping_code
2.3 The Document Object model (DOM) interface

Overview
One of the key skill sets of any frontend web developer is the ability to
manipulate the document dynamically using the DOM, a JavaScript object
that is built after the browser initially builds the document. To manipulate the
DOM means to read, edit, update, or delete the document, including CSS
properties, dynamically. The DOM is the outline of the HTML and content
nodes. The purpose of this activity is to introduce the HTML DOM and to
learn how to change or manipulate the document using JavaScript.
Prepare
2.3.1 The JavaScript DOM explained in 5
minutes
https://www.youtube.com/watch?v=NO5kUNxGIu0
In the link above a short video about DOM can be found. In the video there is
an explanation about how to change the style and html elements of the
website with JavaScript. All the changes uses the attribute ID of the html
elements.
2.3.2 Manipulating documents
https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Client-
side_web_APIs/Manipulating_documents
Hot to manipulate the document structure of a web page and apps?
This is usually done by using the document object model (DOM).
What is the DOM?
It is a set of APIs for controlling HTML and styling information that makes
heavy of the document object.
THE IMPORTANT PARTS OF A WEB BROWSER
Consider the following diagram, which represents the main parts of a
browser directly involved in viewing web pages:
What is the object in JavaScript to represent the window?
The object is Window.
What can be do using the methods available on this object?
 return the window's size
(see Window.innerWidth and Window.innerHeight)
 manipulate the document loaded into that window
 store data specific to that document on the client-side (for example
using a local database or other storage mechanism)
 attach an event handler to the current window, and more.

 The navigator represents the state and identity of the browser (i.e. the
user-agent) as it exists on the web. In JavaScript, this is represented by
the Navigator object. You can use this object to retrieve things like the
user's preferred language, a media stream from the user's webcam,
etc.
 The document (represented by the DOM in browsers) is the actual
page loaded into the window, and is represented in JavaScript by
the Document object. You can use this object to return and manipulate
information on the HTML and CSS that comprises the document, for
example:
 get a reference to an element in the DOM,
 change its text content,
 apply new styles to it,
 create new elements and add them to the current element as
children, or even delete it altogether.
THE DOCUMENT OBJECT MODEL
Next we will how the DOM looks for an HTML structure:
HTML
<!doctype html>
<html lang="en-US">
<head>
<meta charset="utf-8" />
<title>Simple DOM example</title>
</head>
<body>
<section>
<img
src="dinosaur.png"
alt="A red Tyrannosaurus Rex: A two legged dinosaur standing upright like a
human, with small arms, and a large head with lots of sharp teeth." />
<p>
Here we will add a link to the
<a href="https://www.mozilla.org/">Mozilla homepage</a>
</p>
</section>
</body>
</html>

DOM looks like this


Nodes in the DOM
Each entry in the tree is called a node. You can see in the diagram above that
some nodes represent elements (identified as HTML, HEAD, META and so on)
and others represent text (identified as #text). There are other types of nodes
as well, but these are the main ones you'll encounter.
Nodes are also referred to by their position in the tree relative to other
nodes:
 Root node: The top node in the tree, which in the case of HTML is
always the HTML node (other markup vocabularies like SVG and
custom XML will have different root elements).
 Child node: A node directly inside another node. For example, IMG is a
child of SECTION in the above example.
 Descendant node: A node anywhere inside another node. For
example, IMG is a child of SECTION in the above example, and it is also
a descendant. IMG is not a child of BODY, as it is two levels below it in
the tree, but it is a descendant of BODY.
 Parent node: A node which has another node inside it. For
example, BODY is the parent node of SECTION in the above example.
 Sibling nodes: Nodes that sit on the same level in the DOM tree. For
example, IMG and P are siblings in the above example.
ACTIVE LEARNING: BASIC DOM MANIPULATION
An example will be addressed before learning the manipulation of DOM.
Step 1.
To manipulate an element inside the DOM, you first need to select it and
store a reference to it inside a variable as follows:
JS
const link = document.querySelector("a");

Step 2.
Now we have the element reference stored in a variable, we can start to
manipulate it using properties and methods available to it (these are defined
on interfaces like HTMLAnchorElement in the case of <a> element, its more
general parent interface HTMLElement, and Node — which represents all
nodes in a DOM). First of all, let's change the text inside the link by updating
the value of the Node.textContent property.
JS
link.textContent = "Mozilla Developer Network";

Step 3.
We should also change the URL the link is pointing to, so that it doesn't go to
the wrong place when it is clicked on.
JS
link.href = "https://developer.mozilla.org";

The above querySelector() call will match the first <a> element that appears
in the document.
What other ways to select an element and store a reference are available
and what is the recommended modern approach?
The recommended modern approach is Document.querySelector().
 Document.getElementById(), which selects an element with a
given id attribute value, e.g. <p id="myId">My paragraph</p>. The ID is
passed to the function as a parameter, i.e. const elementRef =
document.getElementById('myId').
 Document.getElementsByTagName(), which returns an array-like object
containing all the elements on the page of a given type, for
example <p>s, <a>s, etc. The element type is passed to the function as
a parameter, i.e. const elementRefArray =
document.getElementsByTagName('p').
These two work better in older browsers than the modern methods
like querySelector(), but are not as convenient. Have a look and see what
others you can find!
Why is convenient to use Document.querySelector()?
R. – It is convenient because it allows you to select elements using CSS
selectors.
What method could be used to match and do things to multiple elements?
R. If you wanted to match and do things to multiple elements, you could
use Document.querySelectorAll(), which matches every element in the
document that matches the selector, and stores references to them in
an array-like object called a NodeList.
CREATING AND PLACING NEW NODES
Next, we will work with the html structure bellow:
HTML
<!doctype html>
<html lang="en-US">
<head>
<meta charset="utf-8" />
<title>Simple DOM example</title>
</head>
<body>
<section>
<img
src="dinosaur.png"
alt="A red Tyrannosaurus Rex: A two legged dinosaur standing upright like a
human, with small arms, and a large head with lots of sharp teeth." />
<p>
Here we will add a link to the
<a href="https://www.mozilla.org/">Mozilla homepage</a>
</p>
</section>
</body>
</html>

1. Let's start by grabbing a reference to our <section> element — add the


following code at the bottom of your existing script (do the same with the
other lines too):
JS
const sect = document.querySelector("section");
2. Now let's create a new paragraph using Document.createElement() and
give it some text content in the same way as before:
JS
const para = document.createElement("p");
para.textContent = "We hope you enjoyed the ride.";

3. You can now append the new paragraph at the end of the section
using Node.appendChild():
JS
sect.appendChild(para);

4. Finally for this part, let's add a text node to the paragraph the link sits
inside, to round off the sentence nicely. First we will create the text node
using Document.createTextNode():
JS
const text = document.createTextNode(
" — the premier source for web development knowledge.",
);
5. Now we'll grab a reference to the paragraph the link is inside, and append
the text node to it:
JS
const linkPara = document.querySelector("p");
linkPara.appendChild(text);

DOM methods Use for Example


document.querySelector(eleme to select an const sect =
nt) document.querySelector("sect
element and ion");
store a reference
to it in a variable
Document.querySelectorAll() to match and do
things to multiple
elements
Document.createElement() To create a new const para =
document.createElement("p")
element ;

Node.appendChild() To append a child sect.appendChild(para);

element
Here “sect” is the node or
the parent element for
“para” which will be
appended.
Document.createTextNode() To create a text const text =
document.createTextNode(
node " — the premier source for
web development
knowledge.",
);

MOVING AND REMOVING ELEMENTS


There may be times when you want to move nodes, or delete them from the
DOM altogether. This is perfectly possible.
If we wanted to move the paragraph with the link inside it to the bottom of
the section, we could do this:
JS
sect.appendChild(linkPara);

This moves the paragraph down to the bottom of the section. You might have
thought it would make a second copy of it, but this is not the case
— linkPara is a reference to the one and only copy of that paragraph. If you
wanted to make a copy and add that as well, you'd need to
use Node.cloneNode() instead.
Removing a node is pretty simple as well, at least when you have a reference
to the node to be removed and its parent. In our current case, we just
use Node.removeChild(), like this:
JS
sect.removeChild(linkPara);

When you want to remove a node based only on a reference to itself, which is
fairly common, you can use Element.remove():
JS
linkPara.remove();

This method is not supported in older browsers. They have no method to tell
a node to remove itself, so you'd have to do the following.
JS
linkPara.parentNode.removeChild(linkPara);

MANIPULATING STYLES
A first approach:
Property Use for Example
HTMLElement.style To add inline styles para.style.color =
"white";
directly onto elements para.style.backgroundCol
you want to or = "black";
para.style.padding =
dynamically style. It "10px";
contains inline styling para.style.width =
"250px";
information for each para.style.textAlign =
element in the "center";
document. You can set
properties of this
object to directly
update element styles.

A second approach:
Add the following inside your HTML <head>:
HTML
<style>
.highlight {
color: white;
background-color: black;
padding: 10px;
width: 250px;
text-align: center;
}
</style>

Now we'll turn to a very useful method for general HTML manipulation
— Element.setAttribute() — this takes two arguments, the attribute you want
to set on the element, and the value you want to set it to. In this case we will
set a class name of highlight on our paragraph:
JS
para.setAttribute("class", "highlight");

Which method you choose is up to you; both have their advantages and
disadvantages. The first method takes less setup and is good for simple uses,
whereas the second method is more purist (no mixing CSS and JavaScript, no
inline styles, which are seen as a bad practice). As you start building larger
and more involved apps, you will probably start using the second method
more, but it is really up to you.
ACTIVE LEARNING: A DYNAMIC SHOOPING LIST
In this challenge we want to make a simple shopping list example that allows
you to dynamically add items to the list using a form input and button. When
you add an item to the input and press the button:
 The item should appear in the list.
 Each item should be given a button that can be pressed to delete that
item off the list.
 The input should be emptied and focused ready for you to enter
another item.
The finished demo will look something like this:

To complete the exercise, follow the steps below, and make sure that the list
behaves as described above.
1. To start with, download a copy of our shopping-list.html starting file
and make a copy of it somewhere. You'll see that it has some minimal
CSS, a div with a label, input, and button, and an empty list
and <script> element. You'll be making all your additions inside the
script.
2. Create three variables that hold references to the list (<ul>), <input>,
and <button> elements.
3. Create a function that will run in response to the button being clicked.
4. Inside the function body, start off by storing the current value of the
input element in a variable.
5. Next, empty the input element by setting its value to an empty string
— ''.
6. Create three new elements — a list item (<li>), <span>, and <button>,
and store them in variables.
7. Append the span and the button as children of the list item.
8. Set the text content of the span to the input element value you saved
earlier, and the text content of the button to 'Delete'.
9. Append the list item as a child of the list.
10.Attach an event handler to the delete button so that, when clicked, it
will delete the entire list item (<li>...</li>).
11.Finally, use the focus() method to focus the input element ready for
entering the next shopping list item.
Below, the code is presented.
12. <!DOCTYPE html>
13. <html lang="en-US">
14. <head>
15. <meta charset="utf-8">
16. <meta name="viewport" content="width=device-width,
initial-scale=1.0">
17. <title>Shopping list example</title>
18. <style>
19. li {
20. margin-bottom: 10px;
21. }
22.
23. li button {
24. font-size: 12px;
25. margin-left: 20px;
26. color: #666;
27. }
28. </style>
29. </head>
30. <body>
31.
32. <h1>My shopping list</h1>
33.
34. <div>
35. <label for="item">Enter a new item:</label>
36. <input type="text" name="item" id="item">
37. <button>Add item</button>
38. </div>
39.
40. <ul>
41.
42. </ul>
43.
44. <script>
45. const ulist= document.querySelector('ul');
46. const dataInput= document.querySelector('input');
47. const tapButton= document.querySelector('button');
48.
49. tapButton.addEventListener('click', () => {
50. const myItem = dataInput.value;
51. dataInput.value = '';
52.
53. const eleList = document.createElement('li');
54. const eleSpan =
document.createElement('span');
55. const eleButton =
document.createElement('button');
56.
57. eleList.appendChild(eleSpan);
58. eleSpan.textContent = myItem;
59. eleList.appendChild(eleButton);
60. eleButton.textContent = 'Delete';
61. ulist.appendChild(eleList);
62.
63. eleButton.addEventListener('click', () => {
64. ulist.removeChild(eleList);
65. });
66.
67. dataInput.focus();
68.
69. });
70.
71.
72.
73. </script>
74. </body>
75. </html>

COMMON DOM MANIPULATION CONCEPTS/USE CASES


DOM methods Use for Example
document.querySelector(ele To select an HTML const article =
ment)
element from the document.queryS
document - using elector('articl
the querySelector e');
method.
This line of code
selects the first
instance of an
article element
from the
document and
assigns the
element as a
reference to the
variable
named article.
variable.innerHTML To change the article.innerHT
innerHTML ML = 'innerHTML
property of an supports
existing element. <strong>HTML</s
This line of code trong> tags.
The textContent
uses an existing
property does
variable that has not.';
already selected
an element and
changes its
innerHTML
property value.
Variablename.style.textAlign To change the article.style.t
= ‘right’;
inline CSS style of extAlign =
an element. 'right';
This line of code
changes the text-
align CSS property
of the selected
element.
Variablename.setAttribute(' To change an article.setAttr
class', 'active');
attribute of an ibute('class',
element. 'active');
This line of code
adds and attribute
class to the
element and gives
it a value.
VariablenameElement.classLi An alternative way articleElement.classL
st.add('active'); ist.add('active');
to change an
attribute of an
element,
specifically the
class attribute, is
by directly
manipulating the
element's classList.
This method is
often preferred
when working with
class manipulation
because classList
provides additional
methods like add,
remove, toggle,
and contains,
making it more
convenient and
expressive for
managing classes
on an element.
Document.querySelectorAll() to match and do
things to multiple
elements
Document.createElement() To create a new const para =
document.createElement
element ("p");
const paragraph
=
document.create
Element('p');
Node.appendChild() To append a child sect.appendChild(para);

element
Here “sect” is the
node or the parent
element for “para”
which will be
appended.

article.append(
These lines of code
paragraph,
add content to the
'Hello World
end of the article Addition!');
element.
Document.createTextNode() To create a text const text =
document.createTextNod
node e(
" — the premier source
for web development
knowledge.",
);

node.removeChild(paragr To remove an article.removeChil


d(paragraph);
aph); element from the article.remove();
node document.
.remove(); These lines of code
remove the
paragraph from
the article and
then, the article
itself.

2.3.3 Activity Instructions


This Book of Mormon application will be added upon in future learning
activities. We start now with the interface and basic DOM assignments and
build.
This app allows users to enter their favorite Book of Mormon chapters and
display them on a list that is updated automatically on the screen. Entries can
then be deleted from the displayed list.
1. Create an HTML file named "bom.html" in the week02 folder.
2. Your bom.html HTML document should include the basic meta tags
and an appropriate title.
3. Create an external CSS file and a JS file and place them in appropriate
sub-folders within the week02 folder.
4. Copy and paste the basic interface (the HTML and CSS) from the
following CodePen BOM Top 10.
5. In your blank js file, declare three (3) variables that hold references to
the input, button, and list elements.
const input = document.querySelector('#favchap');
const button = document.querySelector('button');
const list = document.querySelector('______'); //
you need to fill in the blank to reference the HTML
element that is a unordered list element.
6. Create a li element that will hold each entries chapter title and an
associated delete button.
const li = document.createElement('li');

We identified this variable as li, however, that was just for simplicity.
The variable identifier/name did not have to be named the same as the
element being created.

7. Create a delete button.

const deleteButton =
document.createElement('button');

8. Populate the li element variable's textContent or innerHTML with the


input value.
li.textContent = input.value;

textContent is preferred over innerHTML because it is more secure.


However, if you need to include HTML tags, then you would
use innerHTML.
textContent will not render HTML tags. It will display the tags as text.
Why is the value property used?
Because the input variable references an HTML input text field and that is
what is wanted, i.e., the user's entry. Here is the HTML that was
provided: <input type="text" id="favchap" placeholder="Alma 5">
9. Populate the button textContent with a ❌
deleteButton.textContent = '❌';

10. Append the li element variable with the delete button.


li.append(deleteButton);

11. Append the li element variable to the unordered list in your HTML.
list.append(li);

Optional Resources
 DOM Manipulation – by Web Dev Simplified – 14 key techniques in
summary demonstration format. Take special note of the concept
of datasets.
 We do need to consider screen readers and how they will interpret
anything that we have in content. For example, the delete button just
has an emoticon and may not read correctly as the button to remove a
chapter. What can we do? One solution is to create a aria-label
attribute on the button with a value like "Remove Alma 5"
2.4 Handling DOM events
Handling events in JavaScript is a fundamental part of building interactive
web pages. In this activity, you'll learn all about the different events you can
handle, how to handle them, and how to pass data between the event
handler and the rest of your code.
What is an event?
"Events are things that happen in the system you are programming — the
system produces (or "fires") a signal of some kind when an event occurs, and
provides a mechanism by which an action can be automatically taken (that is,
some code running) when the event occurs. Events are fired inside the
browser window, and tend to be attached to a specific item that resides in it.
" - MDNWhat are the events that can be handled?

How to handle events?

How to pass data between the event handler and the rest of the code?
What is an event handler?
2.4.1 JavaScripts Events
https://byui-cit.github.io/learning-modules/modules/js/dom-events/
prepare1/

DOM Events – Event Driven Programing


Event driven programming
Browsers operate by events. Most of the time they sit waiting for something
to happen. They notice everything that does happen, and there are a lot of
possible events...but they won't do anything about it unless we tell them to.
Where can a list of the standard Events used in modern web browsers be
found?
R. –
In the following link a list of standard Events can be found:
https://developer.mozilla.org/en-US/docs/Web/Events

How can we distinguish events of different kinds?


In general, we can distinguish them based on the object emitting the event
including:
 the window object, such as due to resizing the browser,
 the window.screen object, such as due to changes in device
orientation,
 the document object, including the loading, modification, user
interaction, and unloading of the page,
 the objects in the DOM (document object model) tree including user
interactions or modifications,
 the XMLHttpRequest objects used for network requests, and
 the media objects such as audio and video, when the media stream
players change state.

What are some notable events and what are the objects that emit them and
when they are emited?
 the global object window emits an event called 'load' when the page
has finished rendering, meaning that all resources have been
downloaded and acted upon, so that the scripts have been run and the
images displayed,
 the global object window emits an event called 'resize' when the height
or the width of the browser window is changed by a user,
 the DOM object document representing the HTML document emits an
event called 'DOMContentLoaded' when the document has finished
loading,
 the DOM node objects such as div or button emit an event
called 'click' when the user presses the mouse button while the mouse
pointer is on top of the DOM node in the HTML page.

addEventListener
How do we make something happen when a specific event happens?
We do it by using the addEventListener built-in function.
Let's say we had a button in our HTML. When the user clicks on that button
with the mouse, we would like it to read the value of an input, and output it
to another element.
Since functions are special objects in JavaScript, what can we do with
functions?
R. – We can do anything with functions that we can a normal object. This
includes:
 assigning functions to variables,
 passing functions into other functions as arguments,
 returning functions from functions.
What is a callback?
It is the act of passing a function into another function.
Let us see an example of using the built-in function addEventListener:

HTML
<input id="inputBox" type="text" />
<button
id="submitButton">Submit</button>
<p id="output"></p>

JS
const buttonElement =
document.getElementById("submitButton")
;

function copyInput() {
const inputElement =
document.getElementById("inputBox");
const outputElement =
document.getElementById("output");
outputElement.innerHTML =
inputElement.value;
}
buttonElement.addEventListener("click",
copyInput);

The event object


addEventListener will always pass an object containing information about the
event that happened into your callback function. It contains a lot of very
useful information. Run the code below and inspect the event that got logged
out to the console.

JS
// modify the copyInput callback to
receive the event object
function copyInput(event) {
// take a look at the event!
console.log(event);
const inputElement =
document.getElementById("inputBox");
const outputElement =
document.getElementById("output");
outputElement.innerHTML =
inputElement.value;
}

What are some properties of particular interest?


R. –
A few properties of particular interest would
be event.target, event.currentTarget, and event.type

Another example
We saw how to respond to a 'click' event above. What about a key event? If
you refer back to the Event Reference document from earlier we can
find keydown and keyup events. With something like a click, we usually want
to know if a specific thing has been clicked. A keyboard event however often
is not specific to a particular element, so we will listen at the document level.
HTML
<p id="log"></p>

JS
const log =
document.querySelector("#log");

document.addEventListener("keydown",
logKey);

function logKey(e) {
// how do we know which key was
pressed?
console.log(e);
// checkout e.code, e.key, and
e.keyCode
// what is the difference?
}

Did you note the difference between e.code and e.key? Here is a hint.
https://javascript.info/keyboard-events

2.4.2 DOM EVENTS - Ponder activities

This activity will walk us through building a simple To-do application that will
allow you to add a task, mark a task as completed, and remove a task. It is
recommended to review Event Driven Programmming before you start.
You will need your editor open to create a couple of new files for the
following code:
HTML
<!-- events.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible"
content="IE=edge" />
<meta name="viewport"
content="width=device-width, initial-
scale=1.0" />
<title>Events practice:
ToDos</title>
<style>
.todos {
width: 300px;
}
.todos > li {
display: flex;
justify-content: space-between;
align-items: center;
border: 1px solid;
padding: 0.5em;
}
.todos p {
margin: 0;
}
.todos span {
cursor: pointer;
}
.strike {
text-decoration: line-through;
color: gray;
}
</style>
</head>
<body>
<h1>ToDos</h1>
<section>
<label for="todo">Enter
Task</label>
<input name="todo" id="todo" />
<button
id="submitTask">Enter</button>
</section>
<ul id="todoList"
class="todos"></ul>
<script src="events.js"></script>
</body>
</html>

JS
// events.js
let tasks = [];

function renderTasks(tasks) {
// get the list element from the DOM
// loop through the tasks array.
transform (map) each task object into
the appropriate HTML to represent a to-
do.
}

function newTask() {
// get the value entered into the
#todo input
// add it to our arrays tasks
// render out the list
}

function removeTask(taskElement) {
// Note the use of Array.filter to
remove the element from our task array
// Notice also how we are using
taskElement instead of document as our
starting point?
// This will restrict our search to
the element instead of searching the
whole document.
tasks = tasks.filter(
(task) => task.detail !=
taskElement.querySelector('p').innerTex
t
);

// this line removes the HTML element


from the DOM
taskElement.remove();
}

function completeTask(taskElement) {
// In this case we need to find the
index of the task so we can modify it.
const taskIndex = tasks.findIndex(
(task) => task.detail ===
taskElement.childNodes[0].innerText
);
// once we have the index we can
modify the complete field.
// tasks[taskIndex].completed ? false
: true is a ternary expression.
// If the first part is true (left of
the ?), then the value on the left of
the : will get returned, otherwise the
value on the right of the : will be
returned.
tasks[taskIndex].completed =
tasks[taskIndex].completed ? false :
true;
// toggle adds a class if it is not
there, removes it if it is.

taskElement.classList.toggle("strike");
console.log(tasks);
}

function manageTasks(event) {
// did they click the delete or
complete icon?
console.log(event.target);
console.log(event.currentTarget);
// event.target will point to the
actual icon clicked on. We need to get
the parent li to work with however.
HINT: Remember element.closest()? Look
it up if you don't

// because we added 'data-


action="delete"' to each icon in a task
we can access a dataset property on our
target (e.target.dataset.action)
// use that in a couple of if
statements to decide whether to run
removeTask or completeTask
}

// Add your event listeners here


// We need to attach listeners to the
submit button and the list. Listen for
a click, call the 'newTask' function on
submit and call the 'manageTasks'
function if either of the icons are
clicked in the list of tasks.

These activities will be most effective if you TRY them first before you look at
the solution. And after you do look at the solution...DO NOT copy and paste
the code. Read through it, try to understand what it is doing...then go fix your
code.
Activity 1 #
There are 3 functions to be written, and some events to listen for to complete
this simple Todo list application. Begin by reviewing the code you were given.
Pay attention to the comments! Also don't forget to check for errors after
each step!
1. Start with the newTask function. Get the value entered in the '#todo'
input, then add it to the tasks array, and finally call
the renderTasks function.
We need to store two bits of information about each task. The details of the
task, and whether or not it has been completed. The best way to do this is
with a list of Objects. Each task would have the following format:

{ detail: task, completed: false}

2. After completing that attach an event listener to the '#submitTask'


button that will call the newTask function when it is clicked.
3. After making sure that it is working, complete the renderTasks function
next. You can use the following for the markup for each task:

`<li ${task.completed ?
'class="strike"' : ""}>
<p>${task.detail}</p>
<div>
<span data-
function="delete">❎</span>
<span data-
function="complete">✅</span>
</div>
</li>`;

4. Finally we can write the manageTasks() function. When someone clicks


the ❎ it should call the removeTask() function. If they click the ✅ then
the completeTask() should be called.

One way to approach this would be to attach a listener to each button for
each task. But if we up with many tasks that is a lot of listeners to keep track
of. Instead we can take advantage of Event Delegation.
If we click on one of the icons the event will 'bubble' up to the list item and
look for an event listener there. It will then bubble up to the UL and look for a
listener there...so we could simply attach one listener to the parent UL
('#todoList') to catch any click in our list!
One problem though...how do we know which button on which task was
clicked? event.currentTarget always contains a reference to the element the
listener is attached to. event.target always references the element that
triggered the event! (the element clicked on in this case)
If you look at the HTML you were provided for a task you will see data-
action="delete" on the delete icon. This is a custom HTML attribute.
The data- is significant, but the action could have been anything we wanted.
Because we used that preface the browser will package that up for us making
it easy to access. If we inspect event.target.dataset.action should see either
'delete' or 'complete' depending on which icon was clicked. Those we can use
in if statements to decide which function to
call: removeTask() or completeTask()

Solution
let tasks = [];

function taskTemplate(task) {
return `
<li ${task.completed ? 'class="strike"' : ""}>
<p>${task.detail}</p>
<div>
<span data-function="delete">❎</span>
<span data-function="complete">✅</span>
</div>
</li>`
}

function renderTasks(tasks) {
// get the list element from the DOM
const listElement =
document.querySelector("#todoList");
listElement.innerHTML = "";
// loop through the tasks array. transform (map) each
task object into the appropriate HTML to represent a to-
do.
const html = tasks.map(taskTemplate).join("");
listElement.innerHTML = html;
}

function newTask() {
// get the value entered into the #todo input
const task = document.querySelector("#todo").value;
// add it to our arrays tasks
tasks.push({ detail: task, completed: false });
// render out the list
renderTasks(tasks);
}

function removeTask(taskElement) {
// Notice how we are using taskElement instead of
document as our starting point?
// This will restrict our search to the element instead
of searching the whole document.
tasks = tasks.filter(
(task) => task.detail !=
taskElement.querySelector('p').innerText
);
taskElement.remove();
}

function completeTask(taskElement) {
const taskIndex = tasks.findIndex(
(task) => task.detail ===
taskElement.querySelector('p').innerText
);
tasks[taskIndex].completed = tasks[taskIndex].completed
? false : true;
taskElement.classList.toggle("strike");
console.log(tasks);
}

function manageTasks(e) {
// did they click the delete or complete icon?
console.log(e.target);
const parent = e.target.closest("li");
if (e.target.dataset.action === "delete") {
removeTask(parent);
}
if (e.target.dataset.action === "complete") {
completeTask(parent);
}
}

// Add your event listeners here


document.querySelector("#submitTask").addEventListener("c
lick", newTask);
document.querySelector("#todoList").addEventListener("cli
ck", manageTasks);

// render the initial list of tasks (if any) when the


page loads
renderTasks(tasks);

2.4.3 Some common DOM event concepts/use


cases.
Event When is it Use for Example:
triggered?
Click event When a user Handling button buttonElement.addEventL
istener('click',
clicks on an clicks, link clicks, function() {
element or any // Code to execute
interaction when the element is
involving a clicked
});
mouse click.
Keyup Event When a key Handling buttonElement.addEventL
istener('keyup',
is released. keyboard input. function() {
// Code to execute
when a key is released
});
DOMContentLoaded When the Initializing document.addEventListen
er("DOMContentLoaded",
Event HTML JavaScript function() {
document applications // Code to execute
has been when the DOM is parsed
completely });
parsed and
all deferred
scripts have
been
executed.

What does the addEventListener method do?


The addEventListener method takes two arguments: the event name and a
function to execute when the event is triggered.
What is an event handler?
It is the function that is executed when the event is triggered.
What can this function be defined?
the function is a block of code that will be executed when the event is
triggered. The function is also called a callback function because it is called
back when the event is triggered
2.4.3.1 ACTIVITY INSTRUCTIONS
This activity adds functionality to the BOM Top 10 application started in
the previous learning activity on the DOM. We will organize the code to
respond to the Add Chapter button click in order to build the list item. In
addition, the delete button functionality will be added along with some user
interface expectations.

1. Open up your JavaScript file that is supporting


the bom.html application if needed.
2. Create a click event listener for the Add Chapter button using
an addEventListener.

button.addEventListener('click', function() {
// Code to execute when the button is clicked
});

3. Within the Add Chapter button click event function block


( between the opening can closing of the callback function
argument { ... }, do the following:

 Check to make sure the input is not blank before doing the
following remaining tasks in this list. using an if block, otherwise
provide a message or at least do nothing and return
the .focus() to the input field.

if (input.value.trim() !== '') { ... }


What does the .trim()method do?
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
Global_Objects/String/trim
The trim() method of String values removes whitespace from both ends of
this string and returns a new string, without modifying the original string.
To return a new string with whitespace trimmed from just one end,
use trimStart() or trimEnd().
Example
JS
const greeting = ' Hello world! ';

console.log(greeting);
// Expected output: " Hello world! ";

console.log(greeting.trim());
// Expected output: "Hello world!";

JS
const str = " foo ";
console.log(str.trim()); // 'foo'

Should an else branch be added to this conditional?


What code should go into the condition true block { ... }?
 Move the code that you wrote in the last activity into
this if block in order to support the correct flow of the
program.
The user clicks Add Chapter button and the program checks to make
sure that the input field is not empty. Then it is OK to start creating and
populating elements.
 Add an event listener to the delete button that removes
the li element when clicked
JS
deleteButton.addEventListener('click', function () {
list.removeChild(li);
input.focus();
});

 Change the input value to nothing or the empty string to


clean up the interface for the user.
input.value = '';

 Regardless if a list item was created or not, the focus


(active cursor) should be sent to the input element.
input.focus();

2.5 Responsive menus

"Hamburger menus" or equivalent structures support responsive design.


They allow us to clean up layouts because they save space on the page. They
are well-recognized by users, even if they may not know that the common
symbol is called a "hamburger menu".
Here is an example from Google Maps.
Next the HTML, CSS AN JavaScript is showed:

HTML
<a id="menu" href="#"></a>
<nav>
<ul class="navigation">
<li><a href="#">Home</a></li>
<li><a href="#">About Us</a></li>
<li><a href="#">Products</a></li>
<li><a href="#">Feedback</a></li>
<li><a href="#">History</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>

CSS
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Roboto, sans-serif;
}
/* Mobile View ***************/
#menu {
display: block;
font-size: 2rem;
font-weight:700;
text-decoration: none;
padding: .5rem .75rem;
background-color: #eee;
color: #000;
}

#menu::before {
content: "≡";
}

nav {
background-color: tomato;
}
.navigation {
list-style: none;
margin: 0 auto;
max-width: 760px;
}

.navigation li {
display: none;
}
.navigation a {
display: block;
padding: 0.75rem;
text-align: left;
text-decoration: none;
color: black;
font-weight: 700;
transition: 0.5s;
font-size: clamp(1rem, 2vmin, 1.5rem);
}
.navigation a:hover, navigation a:active {
color: white;
background-color: black;
}

.show li {
display: block;
}

#menu.show::before {
content: "X";
}

/* Media Query for wider than mobile viewports. Breakpoint should be


based upon the design and content and use em units to be relative to the
user's font size versus fixed with pixels.*/
@media only screen and (min-width: 40em) {
.navigation {
display: flex;
}
.navigation li {
display: block; /* change state in small view */
flex: 1 1 100%;
}
.navigation a {
text-align: center;
}
#menu {
display: none;
}
}

JS
// Store the selected elements that we are going to use.
const mainnav = document.querySelector('.navigation')
const hambutton = document.querySelector('#menu');
// Add a click event listender to the hamburger button and use a callback
function that toggles the list element's list of classes.
hambutton.addEventListener('click', () => {
mainnav.classList.toggle('show');
hambutton.classList.toggle('show');
});

/* ❔What does toggle mean?


We could write separate add and remove statements. Toggle adds the class
if it does not currently exist or removes the class if it does exist.
The CSS class rules will handle the different views, layouts, and displays.
JavaScript only applies the class value or not.
*/

Result
Wide screen

Small screen
Activity instruction
1. Activity Instructions
2. In your own CodePen account, fork (copy) this CodePen: Responsive
Menu - Start
3. CSS: Move the hamburger menu button to the right upper corner of
the screen by supplying appropriate CSS declarations where there are
currently blanks (______).
4. JavaScript: Complete the JavaScript code by filling in the three (3)
blanks (______) within the menu button event listener.
This example listens to a user initiated event and toggles the given class for
the navigation element. The class name already exists in CSS and is ready to
be applied.
5. CSS: Change the hamburger button closing icon ❎ to something of your
choice that would be appropriate.What does the :: syntax in the CSS
rule selector do?
6. CSS: Wayfinding - Add a rule for the "active" class to let the user know
what page they currently have open by visually changing the
appearance of the one menu item.
In this example the active class is being applied to the About page.
<a href="#" title="About Us" class="active">About Us</a>
"Making it easy for people to navigate around a website or application helps
everyone find what they need quickly and effectively. Clear wayfinding
especially helps people with visual, mobility, or cognitive impairments who
may otherwise find it difficult to understand where they are and how to get
where they want to go." - Harvard University - Digital Accessibility
7. Be sure to Save your changes on your CodePen.

2.6 Debugging – What went wrong

What is an error?
An error could be defined as something wrong with your code.
What types of errors exist?
 SYNTAX ERRORS: Often spelling or other mis-typing errors where we
try to use a defined variable or function that does not exist. These
show up as error messages in the console, and are usually easier to fix.
 LOGIC ERRORS: Logic errors happen when your code works...just not
like you need it to. It doesn't give the correct output or result. There is
often not a defined error message that shows which means that finding
and fixing these is often harder.
Running and debugging JavaScript in the Browser
Javascript was originally created to be run in a browser and much of it still is.
Because of this we will focus on debugging techniques for the browser.
1. Open a sandbox folder up in your editor. In the sandbox folder create
an html file called debugging.html with the html for a basic page. (Hint:
In VS Code type ! in your blank .html file...then press the tab key. You
are welcome...;)
2. Create a file called debugging.js
3. Add a script element to your debugging.html file. The script element is
how we let the browser know that there is some Javascript code that it
needs to fetch and execute.

There are a few special elements in HTML.


They are special because the contents of
those elements are not treated as HTML, but
something different.
and <style> are the most common of these
<script>

special tags. In the case of <style> the contents


are treated as CSS (which we won't talk
about much in this course). For <script> the
contents are treated as Javascript.
The <script> can be used in two ways: we can
add the code we want executed inside of the
element, ie:
<script>
let myVar = 3;
</script>
...or we can put our Javascript code inside of
a separate file and link it in:
<script src="debugging.js"></script>
This second method is considered best
practice and is how you should run our
Javascript. The other method is often used for
quick proof-of-concept hacking, but the code
will usually get moved into a JS file if the code
is going to be kept.

4. Add the following code to your debugging.js file:

const PI = 3.14;
const radius = 3;
let area = 0;
area = radius * radius * pi;
radius = 4;
area = radius * radius * pi;

5. Open your HTML file in a browser. (If you are using VS Code and
installed the LiveServer extension you can right click on the name of
the file in VS Code and select the 'Open with LiveServer') There is
nothing on the screen! This is normal...in our HTML we didn't ask for
anything to be on the screen. Open up the developer tools and switch
to the CONSOLE tab.
6. Notice that there are errors listed. These are syntax errors that will
keep our code from running correctly until the are fixed.
7. Switch to the SOURCES tab in the developer tools. Click on
the debugging.js file in the left pane. You should be able to see the
code you wrote.
8. Click on the line number for line 1. It should add a blue arrow on it. We
have just set a breakpoint. If you refresh the browser the code
execution will now stop on line 1 at our breakpoint.
9. The Resume button should be blue at this point. That means the
execution of our code is paused. At this point we could click the
Resume button to resume the execution of the program, or Step over,
or step into. STEP INTO is for functions, which we don't have yet. so
click the STEP OVER button to advance to the next line in the code.
10.Hover your mouse cursor over the word PI in the Sources tab. You
should see a little popup with '3.14' show up. This indicates what the
current value in that variable is. Do not underestimate how valuable
this inspect ability is!
11.If you click STEP OVER a few more times we will get to the line with the
first syntax error and our execution will end. (Resume button will no
longer be a blue 'Play' button.)
12.Clicking on the line number for line 1 again will remove the breakpoint.

Optional resources
https://www.youtube.com/watch?v=gaminoBsQx0
Chapter 3 Design principles, CSS Concepts: Pseudo
Selection, Image file formats for the web, Responsive
images, Java script Arrays, JavaScript Functions

3.1 Design principles

The principles of good design should be practiced in web design to promote a


positive user experience. One goal of this course is to provide a reasonable
foundation in good design. These principles should be understood, practiced,
and continuously improved upon. It takes applied practice and actively
seeking constructive feedback from others.
"Effective web design and art are not the same. But many psychological and
design principles apply to websites. You can design a great website by
applying the relevant aspects of those laws to your layout, typography, and
images. Design for the user and your business objectives." - Peep Laja - CXL
What are the psychological and design principles that apply to websites?
3.1.1 8 fundamental principles of effective
Web Design
What does mean for a website having a good accessibility?
It mean that the website can work for different devices, can be found in
different languages, it can be used in different locations and for people with
different cognitive capacity. It implies that the website was created and
developed so that persons with impairments can use them.
What does visual hierarchy refer and how is it accomplished?
It refers to the arrangement of elements of the website to show what matters
the most to the user. This is accomplished by using proportion, color, images,
contrast, typography, whitespace, texture, and style.
How many colors are recommended for a color palette for a website?
Five colors are recommended and complementary color.
What are the simplest fonts to read online?
Sans serif fonts such as Arial, Helvetica, verdana
Why is important to use a web safe font?
It is important to assure that the text of a website always display correctly.
What is a web-safe font?
https://www.freecodecamp.org/news/web-safe-fonts/
Web safe fonts are fonts that are included with most operating systems, the
implication of such high availability is that a designer can expect typography
involving web safe fonts to appear exactly as intended to most users. Below
are non-exhaustive lists of some fonts that are considered web safe at the
time of writing, categorized by CSS generic font families.
Web safe serif fonts:
 Georgia
 Times New Roman
Web safe sans-serif fonts:
 Arial
 Tahoma
 Trebuchet MS
 Verdana
Web safe monospaced fonts:
 Courier New
It is worth noting that font stacks with fallback options including a generic
font family should still be used even if your design uses only web safe fonts.
For example:

Typography
What is the optimal font size?
16 px is the optimal font size.
How many point sizes are recommended?

A maximum of three point sizes is advised for a streamlined design.


How many fonts is it ideal to use?
It is ideal to use a maximum of 3 fonts for headers, body text, and
components such as buttons.
What is the F-based pattern pattern?
This is how people used to take a look of a website, from left to right and
from top to bottom.
3.1.2 Learn the most common Design
mistakes by Non Designers
https://www.youtube.com/watch?v=mOA0WH00reA
Too wordy, too many text on the design.
Poor readability, too many line of text. Keep paragraph very short.
Too many font. It is good to use variations of a font like italic.
Not choosing the right colors.
Lack of negative space.
Place elements arbitrarily.
Failing to create contrast.
Not scaling elements properly.
Hard to read text

Inappropriate font combination

Inadequate space between lines


Using raster images

Striving for complete symmetry


It is not obligatory to reach symmetry but a good balance between elements
Failing to communicate effectively
Not necessary to use many icons.
No being consistent

3.1.3 Web design principles summary

 Clarity and Simplicity: Keep the design clean and uncluttered. Use
ample whitespace to guide the user's focus and avoid overwhelming
them with too much information at once.
 Consistency: Maintain a consistent visual language throughout the
design. This includes using consistent typography, color schemes, and
layout patterns across different pages or sections of your design.
 Hierarchy: Establish a clear hierarchy of information to help users
understand the relative importance of different elements on the page.
Use techniques like size, color, and typography to emphasize important
content.
 Accessibility: Ensure that your design is accessible to all users,
including those with disabilities. This may involve considerations such
as providing alternative text for images, using sufficient color contrast,
and implementing keyboard navigation.
 Feedback: Provide clear feedback to users when they interact with
elements on the page. This could include visual cues such as button
states or animations to indicate that an action has been successfully
completed.
 User-Centric Design: Design with the needs and preferences of your
target audience in mind. Conduct user research to understand their
goals, behaviors, and pain points, and tailor your design accordingly.
 Visual Appeal: Use visually appealing elements such as high-quality
images, engaging animations, and attractive typography to capture the
user's attention and create a memorable experience.

3.2 CSS Concepts: Pseudo Selection

3.2.1 Pseudo-classes
https://www.w3schools.com/css/css_pseudo_classes.asp
What is a pseudo-class useful for?
For example, it can be used to:
 Style an element when a user mouses over it
 Style visited and unvisited links differently
 Style an element when it gets focus
What is the sintax?
The sintax is:
selector:pseudo-class {
property: value;
}

Anchor Pseudo-classes
It is used to display links in different ways

HTML CSS
/* unvisited link */
a:link {
color: #FF0000;
<body> }

<h2>Styling a link depending on /* visited link */


a:visited {
state</h2> color: #00FF00;
}
<p><b><a href="default.asp"
target="_blank">This is a /* mouse over link */
a:hover {
link</a></b></p> color: #FF00FF;
<p><b>Note:</b> a:hover MUST }
come after a:link and a:visited in the
/* selected link */
CSS definition in order to be a:active {
effective.</p> color: #0000FF;
<p><b>Note:</b> a:active MUST }
come after a:hover in the CSS
definition in order to be
effective.</p>

</body>
Result
Note: a:hover MUST come after a:link and a:visited in the CSS definition in
order to be effective! a:active MUST come after a:hover in the CSS definition
in order to be effective! Pseudo-class names are not case-sensitive.

Pseudo-classes and HTML classes


Pseudo-classes can be combined with HTML classes:
When you hover over the link in the example, it will change color:

<!DOCTYPE html> a.highlight:hover {


<html> color: #ff0000;
<head> font-size: 22px;
</head> }
<body>

<h2>Pseudo-classes and HTML


Classes</h2>

<p>When you hover over the first


link below, it will change color and
font size:</p>

<p><a class="highlight"
href="css_syntax.asp">CSS
Syntax</a></p>
<p><a href="default.asp">CSS
Tutorial</a></p>

</body>
</html>
Hover on <div>
An example of using the :hover pseudo-class on a <div> element:
HTML CSS
<!DOCTYPE html>
<html> div {
<head> background-color: green;
</head> color: white;
<body> padding: 25px;
text-align: center;
<p>Mouse over the div element }
below to change its background
color:</p> div:hover {
background-color: blue;
<div>Mouse Over Me</div> }

</body>
</html>
Simple Tooltip Hover
Hover over a <div> element to show a <p> element (like a tooltip):
HTML CSS
<!DOCTYPE html>
<html> p{
<head> display: none;
</head> background-color: yellow;
<body> padding: 20px;
}
<div>Hover over this div element to
show the p element div:hover p {
<p>Tada! Here I am!</p> display: block;
</div> }

</body>
</html>

CSS - The :first-child Pseudo-class


The :first-child pseudo-class matches a specified element that is the first child
of another element.

Match the first <p> element


In the following example, the selector matches the first <i> element in all <p>
elements:
HTML CSS
<!DOCTYPE html>
<html> p:first-child {
<head> color: blue;
</head> }
<body>
<p>This is some text.</p>
<p>This is some text.</p>

<div>
<p>This is some text.</p>
<p>This is some text.</p>
</div>

</body>
</html>

Match all <i> elements in all first child <p> elements


In the following example, the selector matches all <i> elements in <p>
elements that are the first child of another element:
HTML CSS
<!DOCTYPE html>
<html>
<head> p:first-child i {
</head> color: blue;
<body> }

<p>I am a <i>strong</i> person. I am


a <i>strong</i> person.</p>
<p>I am a <i>strong</i> person. I am
a <i>strong</i> person.</p>

<div>
<p>I am a <i>strong</i> person. I
am a <i>strong</i> person.</p>
<p>I am a <i>strong</i> person. I
am a <i>strong</i> person.</p>
</div>

</body>
</html>

CSS – The lang Pseudo-class


The :lang pseudo-class allows you to define special rules for different
languages.
In the example below, :lang defines the quotation marks for <q> elements
with lang="no":
HTML and CSS
<!DOCTYPE html>
<html>
<head>
<style>
q:lang(no) {
quotes: "~" "~";
}
</style>
</head>
<body>

<p>Some text <q lang="no">A quote in a paragraph</q> Some text.</p>


<p>In this example, :lang defines the quotation marks for q elements with
lang="no":</p>

</body>
</html>

MORE EXAMPLES
Adding different styles to hyperlinks
HTML & CSS
<!DOCTYPE html>
<html>
<head>
<style>
a.one:link {color:#ff0000;}
a.one:visited {color:#0000ff;}
a.one:hover {color:#ffcc00;}

a.two:link {color:#ff0000;}
a.two:visited {color:#0000ff;}
a.two:hover {font-size:150%;}

a.three:link {color:#ff0000;}
a.three:visited {color:#0000ff;}
a.three:hover {background:#66ff66;}

a.four:link {color:#ff0000;}
a.four:visited {color:#0000ff;}
a.four:hover {font-family:monospace;}

a.five:link {color:#ff0000;text-decoration:none;}
a.five:visited {color:#0000ff;text-decoration:none;}
a.five:hover {text-decoration:underline;}
</style>
</head>
<body>

<h2>Styling Links</h2>

<p>Mouse over the links and watch them change layout:</p>

<p><b><a class="one" href="default.asp" target="_blank">This link changes


color</a></b></p>
<p><b><a class="two" href="default.asp" target="_blank">This link changes
font-size</a></b></p>
<p><b><a class="three" href="default.asp" target="_blank">This link
changes background-color</a></b></p>
<p><b><a class="four" href="default.asp" target="_blank">This link
changes font-family</a></b></p>
<p><b><a class="five" href="default.asp" target="_blank">This link changes
text-decoration</a></b></p>

</body>
</html>
Use of :focus

<!DOCTYPE html>
<html>
<head>
<style>
input:focus {
background-color: yellow;
}
</style>
</head>
<body>

<form action="/action_page.php" method="get">


First name: <input type="text" name="fname"><br><br>
Last name: <input type="text" name="lname"><br><br>
<input type="submit" value="Submit">
</form>

</body>
</html>

All CSS Pseudo Classes


Selector Example Example description

:active a:active Selects the active link

:checked input:checked Selects every checked <input>


element

:disabled input:disabled Selects every disabled <input>


element

:empty p:empty Selects every <p> element that


has no children

:enabled input:enabled Selects every enabled <input>


element

:first-child p:first-child Selects every <p> elements


that is the first child of its
parent

:first-of-type p:first-of-type Selects every <p> element that


is the first <p> element of its
parent

:focus input:focus Selects the <input> element


that has focus

:hover a:hover Selects links on mouse over

:in-range input:in-range Selects <input> elements with


a value within a specified
range
:invalid input:invalid Selects all <input> elements
with an invalid value

:lang(language) p:lang(it) Selects every <p> element


with a lang attribute value
starting with "it"

:last-child p:last-child Selects every <p> elements


that is the last child of its
parent

:last-of-type p:last-of-type Selects every <p> element that


is the last <p> element of its
parent

:link a:link Selects all unvisited links

:not(selector) :not(p) Selects every element that is


not a <p> element

:nth-child(n) p:nth-child(2) Selects every <p> element that


is the second child of its parent

:nth-last-child(n) p:nth-last-child(2) Selects every <p> element that


is the second child of its
parent, counting from the last
child

:nth-last-of-type(n) p:nth-last-of-type(2) Selects every <p> element that


is the second <p> element of
its parent, counting from the
last child
:nth-of-type(n) p:nth-of-type(2) Selects every <p> element that
is the second <p> element of
its parent

:only-of-type p:only-of-type Selects every <p> element that


is the only <p> element of its
parent

:only-child p:only-child Selects every <p> element that


is the only child of its parent

:optional input:optional Selects <input> elements with


no "required" attribute

:out-of-range input:out-of-range Selects <input> elements with


a value outside a specified
range

:read-only input:read-only Selects <input> elements with


a "readonly" attribute
specified

:read-write input:read-write Selects <input> elements with


no "readonly" attribute

:required input:required Selects <input> elements with


a "required" attribute specified

:root root Selects the document's root


element

:target #news:target Selects the current active


#news element (clicked on a
URL containing that anchor
name)

:valid input:valid Selects all <input> elements


with a valid value

:visited a:visited Selects all visited links

All CCS Pseudo Elements

Selector Example Example description

::after p::after Insert content after every <p>


element

::before p::before Insert content before every


<p> element

::first-letter p::first-letter Selects the first letter of


every <p> element

::first-line p::first-line Selects the first line of every


<p> element

::marker ::marker Selects the markers of list


items

::selection p::selection Selects the portion of an


element that is selected by a
user
3.2.2 :root Pseudo-Class

What selector is identical to :root and what is its difference?


A. – The html selector is identical to :root, except that this last specificity
is higuer.
How can variables be declared in CSS?
A.- By using :root Pseudo-Class:
:root {
--main-color: hotpink;
--pane-padding: 5px 42px;
}
https://developer.mozilla.org/en-US/docs/Web/CSS/
Using_CSS_custom_properties

An example of using the :root with custom properties or variables


/* Define --main-bg-color here */
:root {
--main-bg-color: cornflowerblue;
}

/* For each class, set some colors */


.one {
background-color: var(--main-bg-color);
}
.two {
color: black;
background-color: aquamarine;
}
.three {
background-color: var(--main-bg-color);
}
.four {
background-color: var(--main-bg-color);
}
.five {
background-color: var(--main-bg-color);
}
3.2.3 CSS Pseudo-elements
https://www.w3schools.com/css/css_pseudo_elements.asp
What can Pseudo-elements be useful for?
A.- Style the first letter, or line, of an element
Insert content before, or after, the content of an element.
What is the sintax?
selector::pseudo-element {
property: value;
}

The ::first-line Pseudo-element


The ::first-line pseudo-element is used to add a special style to the first line of
a text.
The following example formats the first line of the text in all <p> elements:
HTML & CSS
<!DOCTYPE html>
<html>
<head>
<style>
p::first-line {
color: #ff0000;
font-variant: small-caps;
}
</style>
</head>
<body>

<p>You can use the ::first-line pseudo-element to add a special effect to the
first line of a text. Some more text. And even more, and more, and more, and
more, and more, and more, and more, and more, and more, and more, and
more, and more.</p>

</body>
</html>

Note: The ::first-line pseudo-element can only be applied to block-level


elements.
The following properties apply to the ::first-line pseudo-element:
 font properties
 color properties
 background properties
 word-spacing
 letter-spacing
 text-decoration
 vertical-align
 text-transform
 line-height
 clear
The ::first-letter Pseudo-element
The ::first-letter pseudo-element is used to add a special style to the first
letter of a text.
The following example formats the first letter of the text in all <p> elements:
HTML &CSS
<!DOCTYPE html>
<html>
<head>
<style>
p::first-letter {
color: #ff0000;
font-size: xx-large;
}
</style>
</head>
<body>

<p>You can use the ::first-letter pseudo-element to add a special effect to the
first character of a text!</p>

</body>
</html>

Note: The ::first-letter pseudo-element can only be applied to block-level


elements.
The following properties apply to the ::first-letter pseudo- element:
 font properties
 color properties
 background properties
 margin properties
 padding properties
 border properties
 text-decoration
 vertical-align (only if "float" is "none")
 text-transform
 line-height
 float
 clear

Pseudo-elements and HTML Classes


Pseudo-elements can be combined with HTML classes:

HTML & CSS


<!DOCTYPE html>
<html>
<head>
<style>
p.intro::first-letter {
color: #ff0000;
font-size: 200%;
}
</style>
</head>
<body>

<p class="intro">This is an introduction.</p>


<p>This is a paragraph with some text. A bit more text even.</p>

</body>
</html>

Multiple Pseudo-elements
Several pseudo-elements can also be combined.
In the following example, the first letter of a paragraph will be red, in an xx-
large font size. The rest of the first line will be blue, and in small-caps. The
rest of the paragraph will be the default font size and color:

HTML & CSS


<!DOCTYPE html>
<html>
<head>
<style>
p::first-letter {
color: #ff0000;
font-size: xx-large;
}

p::first-line {
color: #0000ff;
font-variant: small-caps;
}
</style>
</head>
<body>

<p>You can combine the ::first-letter and ::first-line pseudo-elements to add


a special effect to the first letter and the first line of a text!</p>

</body>
</html>

CSS - The ::before Pseudo-element


The ::before pseudo-element can be used to insert some content before the
content of an element.
The following example inserts an image before the content of each <h1>
element:
HTML & CSS
<!DOCTYPE html>
<html>
<head>
<style>
h1::before {
content: url(smiley.gif);
}
</style>
</head>
<body>

<h1>This is a heading</h1>
<p>The ::before pseudo-element inserts content before the content of an
element.</p>

<h1>This is a heading</h1>

</body>
</html>

CSS - The ::after Pseudo-element


The ::after pseudo-element can be used to insert some content after the
content of an element.
The following example inserts an image after the content of each <h1>
element:
<!DOCTYPE html>
<html>
<head>
<style>
h1::after {
content: url(smiley.gif);
}
</style>
</head>
<body>

<h1>This is a heading</h1>
<p>The ::after pseudo-element inserts content after the content of an
element.</p>

<h1>This is a heading</h1>

</body>
</html>

CSS - The ::marker Pseudo-element


The ::marker pseudo-element selects the markers of list items.
The following example styles the markers of list items:

<!DOCTYPE html>
<html>
<head>
<style>
::marker {
color: red;
font-size: 23px;
}
</style>
</head>
<body>

<ul>
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
</ul>

<ol>
<li>First</li>
<li>Second</li>
<li>Third</li>
</ol>

</body>
</html>
CSS - The ::selection Pseudo-element
The ::selection pseudo-element matches the portion of an element that is
selected by a user.
The following CSS properties can be applied
to ::selection: color, background, cursor, and outline.
The following example makes the selected text red on a yellow background:

<!DOCTYPE html>
<html>
<head>
<style>
::selection {
color: red;
background: yellow;
}
</style>
</head>
<body>
<h1>Select some text on this page:</h1>

<p>This is a paragraph.</p>
<div>This is some text in a div element.</div>

</body>
</html>

Picking emojis on Windows OS


https://support.microsoft.com/en-us/windows/windows-keyboard-tips-and-
tricks-588e0b72-0fff-6d3f-aeee-6e5116097942
3.3 Image file formats for the web

What are the image format that offers better compression to support faster
page loads?
A.- They are SVG and WebP image format.
"WebP is a modern image format that provides superior lossless and lossy
compression for images on the web. Using WebP, webmasters and web
developers can create smaller, richer images that make the web faster."
- developers.google.com
The SVG format is a vector image format that is used for two-dimensional
graphics with support for interactivity and animation. "As such, it's a text-
based, open Web standard for describing images that can be rendered cleanly
at any size and are designed specifically to work well with other web
standards including CSS, DOM, JavaScript, and SMIL. SVG is, essentially, to
graphics what HTML is to text." - MDN
3.3.1 Common image formats
https://www.youtube.com/watch?v=Zx0CacsiDZ4
Types
BMP Don’t use in web
GIF Siomple animation,
support transparency
but not alpha
transparency
PNG Supports transparency
and alpha transparency
JPG Supports compression
SVG They are not resolution
dependent

3.3.2 WebP image format


https://developers.google.com/speed/webp?hl=es-419
Some terms that you may not be familiar with include:
 Lossless Compression - File compression that maintains the original
data using sophisticated, redundancy, replacement algorithms.
 Lossy Compression - File compression that uses approximations and
partial data to represent the original media source.
 Transparency - The image property representing the amount or level of
transmission of background color through the image.
3.3.3 Image file type and format guide
https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Image_types
"The older formats like PNG, JPEG, GIF have poor performance compared to
newer formats like WebP and AVIF, but enjoy broader "historical" browser
support. The newer image formats are seeing increasing popularity as
browsers without support become increasingly irrelevant (meaning have
virtually zero market share)." – MDN

3.3.4 Image optimization


https://byui-cse.github.io/wdd131-ww-course/resources/image-
optimization.html
 Overview
One of the concerns of frontend web design and development is site
performance. A common element affecting performance is image load time.
That is where image optimization becomes a factor because images account
for most of the downloaded bytes from the web server. The art of
optimization is the process of trying to find the balance between design
quality needs and file size.
Here are some 2022 almanac facts:
 99.9% of pages on the web generate at least one request for an image
resource.
 Most images (54%) are presented in landscape aspect ratio versus
square or portrait.
 "Images are the poster child for balance between performance-
enhancing technologies and asset byte size."
 Basic Steps of Optimization
Often the original photos that we work with are very large and those photos
need to be scaled down to the largest size that is actually needed on the page
given the design and layout plan. Software can be used to crop, reduce, and
optimize the images. These are the basic steps supported by most photo
editing packages:
1. Crop the original image to the critical content keeping in mind design
principles, like the rule of thirds, and the site or section purpose.
2. Resize the image to the maximum size that you actually need in the
design of your site. That image will then be saved in smaller formats,
possibly with slightly different design to match the design and layout in
smaller views, meaning, smart phone, tablet.
3. Reduce the quality of the image to an acceptable level, thus reducing
its file size.
Image optimization is some of that low-hanging fruit which we can employ
without a staggering amount of investment of time. Additional image
handling techniques include:
• Resizing images during the build process using script
• Creating multiple image sizes and use srcset to let the browser or user
agent decide which image to load
• Use an image CDN (Content Delivery Network)
 Measuring Performance / Page Weight
Check the size of the page resources by using the Dev Tools Network tab.
Reload the page using a cache emptying "hard" refresh. The course standard
will be outlined in the course development standards checklist and in the
assessment rubrics.
 Editing Tools
The following list of software applications is in no way comprehensive but
rather provides some healthy options of tools that will help you manipulate
images including the process of optimizing images. You may elect to use any
tool you wish.
 Adobe Photoshop: Adobe Photoshop is the most popular software
application when it comes to actually being named on front-end web
designer job descriptions under qualifications or desired experience. It
is an industry standard. This course does not require or teach
Photoshop even though it certainly ranks high in the skill set for front-
end web designers and developers. The tool has a built-in optimization
process known as Save for web. You can specify some constraints via a
setting that should help in finding this balance mentioned above.
 GIMP or GNU Image Manipulation Program, is an image manipulation,
image authoring, and photo editing software that is freely distributed
and has a lot of support online. It may be a step down from Photoshop,
but it supports a large percentage of the actual work that is essential in
graphical design.
 TinyJPG / TinyPNG is a free online application that will reduce JPEG
images through encoding.
 PIXLR x is a web-based photo-editor that will let you crop, resize, and
enhance your photos for free.
There are many other tools and you are free to use any image editing too.
Many of these come with excellent support including the following:
 Squoosh.app - online photo editing
 JPEG Optimizer - online jpg file editing
 ImageOptim (Here is an absolute beginners guide for use on Mac
computers)
 File Optimizer (for use on Windows)
Additional resources:
Para optimizar el tiempo de carga
https://web.dev/explore/fast?hl=es-419#optimize-your-images
https://www.youtube.com/watch?v=5fLW5Q5ODiE&t=9s

3.4 Responsive images

What is the work and the objective of responsive image design?


A. It is to support smaller page weights and to deliver content based upon
screen size. The objective is to reduce page weight while being conscious of
image clarity and functionality in each size and subsequent viewport (the
visible are of a web page).
https://developer.mozilla.org/en-US/docs/Learn/HTML/
Multimedia_and_embedding/Responsive_images
What is the alternative to one-size-fits-all approach to images?
A. The alternative is serving different image sizes to different devices. It is
common to serve 3-5 different sizes of an image, this is better for
performance, but will take up more space on your servers and require writing
a tiny bit more HTML.
What is the effect of applying the srcset attribute to images using the
picture and source elements?
A. The browser parses the responsive image sintax and decides which image
is the best match.
The srcset attribute allows the browser to choose the best image to display
based on the device's screen size and resolution.
What techniques of image optimization and html elements should be
applied before using responsive image techniques?
A.
 The viewport meta element has been properly applied to the
document.
 The images to be used have been optimized for the web by
o Limiting the images' width and height (dimensions) to no more
than is necessary for the page design in any view size.
o The images are of a valid web type/format.
o The images are compressed to reduce their overall file size. In
many image editing software packages this is referred to as
reducing the 'quality'.
 The developer has designed and saved images for use on different
screen sizes.
How to change the image displayed to suit different image display size?
A. By using the <picture> element. This is a wrapper containing several
<source> elements that provide different sources for the browser to choose
from, followed by the all-important <img> element.
The code in responsive html looks like so:
HTML
<picture>
<source media="(max-width: 799px)" srcset="elva-480w-close-portrait.jpg" />
<source media="(min-width: 800px)" srcset="elva-800w.jpg" />
<img src="elva-800w.jpg" alt="Chris standing up holding his daughter Elva" />
</picture>

 The <source> elements include a media attribute that contains a


media condition — as with the first srcset example, these conditions
are tests that decide which image is shown — the first one that returns
true will be displayed. In this case, if the viewport width is 799px wide
or less, the first <source> element's image will be displayed. If the
viewport width is 800px or more, it'll be the second one.
 The srcset attributes contain the path to the image to display. Just as
we saw with <img> above, <source> can take a srcset attribute with
multiple images referenced, as well as a sizes attribute. So, you could
offer multiple images via a <picture> element, but then also offer
multiple resolutions of each one. Realistically, you probably won't want
to do this kind of thing very often.
 In all cases, you must provide an <img> element, with src and alt, right
before </picture>, otherwise no images will appear. This provides a
default case that will apply when none of the media conditions return
true (you could actually remove the second <source> element in this
example), and a fallback for browsers that don't support
the <picture> element.
Example of using the srcset attribute with the picture and source elements:
<picture>
<source srcset="images/hero-large.webp" media="min-width:
1000px">
<source srcset="images/hero-medium.webp" media="min-width:
550px">
<img src="images/hero-small.webp" alt="Orem Utah Temple"
width="400" height="200">
</picture>

The picture tag has a reference to three different images, two sources and a
default img tag. Which image is rendered by the browser depends upon the
media queries. The following is a description of the rendering process:
Is the width of the browser at least a minimum width of 1000px? If so, the
srcset path replaces the src from the img tag and the hero-large.webp image
is displayed. If the browser view width is less than 1000px then the browser
tests the next source given.
Is the width of the browser at least a minimum width of 550px? If so,
the hero-medium.webp image is used.
The default is the img tag src reference to hero-small.webp.
Activity instructions
File and Folder Setup
1. If it does not already exist, create a folder named "week03" in the
wdd131 directory.
2. Add a new file named "responsive-images.html" to that week03 folder.
3. Provide a basic HTML structure to the responsive-images.html file.
4. If it does not already exist, add a "styles" folder to the week03 folder
and add a new CSS file named "responsive-images.css" to that styles
folder.
5. If it does not already exist, create a folder named "images" in your
week03 directory.
Image Editing
1. Navigate to Temple List and click on a temple link of your choice to gain
access to that temple's Media Gallery.
2. In the Media Gallery of the temple, click on one of the images and
download a Large version of the image by using Save Image As... or
equivalent method.
3. Using your image editing, like Pixlr E, load the downloaded image file
and create three (3) different images:
o Each image should have a different crop (Art Direction)
o Save all three images in the WebP file format with a quality
around 50%.
o Create a small version named "hero-small.webp" that is 500px in
width by 250px in height.
o Create a medium version named "hero-medium.webp" that is
1000px in width by 500px in height.
o Create a large version named "hero-large.webp" that is 1500px
in width by 750px in height.
Note that the ratios of all these images are 2:1 for consistency.
4. Put all of these images in your images folder for week03.
HTML: Picture Element
1. In your html file, add a main element with a generic division element
with the class of "hero
2. Within the div element, add a picture element.
3. Within the picture element, add a source element with attributes
for media and srcset
Emmet Shorthand (enter syntax + tab):
main>div.hero>picture>source:media*2+img
4. Set the path for the srcset to the largest image.
5. Set the media attribute to min-width: 1000px which is the width of the
large hero image created earlier.
6. If needed, copy and paste the source line of markup and then change
the image to the medium image and the min-width to 500px.
Neither of these images will render on a page. An img element with a src is
needed.
7. Add the img element with a src referencing the smallest image.
8. Set the alt attribute value to a description of the image.
9. Set the width and height attributes to the width and height of the
largest image. What should the values for width and height be since we
have a 500px by 250px photo and a 1000px by 500px photo and a
1500px by 750px photo? The important point is to maintain the aspect
ratio of the image as the ratio is used by the browser to render the
space required by the image once it loads. We can use the large image
of 1500 and 750 or any equivalent ratio.
Example:
<div class="hero">
<picture>
<source srcset="images/hero-large.webp" media="(min-
width: 1000px)">
<source srcset="images/hero-medium.webp" media="(min-
width: 500px)">
<img src="images/hero-small.webp" alt="Temple name and
location" width="500" height="250">
</picture>
</div>

Why are img width and height necessary?


Some of the most common causes of a layout shift or reflow during the
rendering of a page are images, ads, embeds, and iframes without
dimensions. "Layout shifts can be distracting to users. Imagine you've started
reading an article when all of a sudden elements shift around the page,
throwing you off and requiring you to find your place again. This is very
common on the web, including when reading the news, or trying to click
those 'Search' or 'Add to Cart' buttons. Such experiences are visually jarring
and frustrating. They are often caused when visible elements are forced to
move because another element was suddenly added to the page or resized."
Optimize Cumulative Layout Shift - Osmani and Pollard, web.dev

CSS:
1. In the style sheet, enable responsive behavior on the image by setting
the width of the img element to 100% and the height to auto (or vice-
versa). This is the easiest way to maintain the image aspect ratio.
2. .hero img {
3. width: 100%;
4. height: auto;
}
Or to use object-fit with set image containers. Just be mindful of the art
direction with the responsive results.
.hero img {
width: 100%;
height: 100%;
object-fit: cover;
}
Another solution is to use the aspect-ratio property.
We want responsive images to maintain their intrinsic aspect ratio.
Alternating the aspect ratio by setting the width AND height to values
(including setting the height to relative measure 100%) in order to fill your
design space may distort and pixelate the image. Lighthouse will report on
major aspect ratio violations.
More information about aspect ratios.
Optional resources:
 Make Your Site Lightning Fast With Responsive Images - Web Dev
Simplified
 Working with Responsive Images | (6:49 mins, Responsive Images
Transcript)
 Serve Responsive Images - Katie Hempenius - dev.to
 Picture Element - Paul Cheney
 Aspect-Ratio CSS Property - Una Kravets - web.dev

3.5 Java script Arrays


3.5.1 Creating an array
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/
Indexed_collections#sparse_arrays
3.5.2 ARRAY
The Array object, as with arrays in other programming languages,
enables storing a collection of multiple items under a single variable name,
and has members for performing common array operations.
3.5.3 DESCRIPTION
What are the characteristics of Array objects?
A. JSArr (JavaScript arrays)
JavaScript arrays are resizable and can contain a mix of different data types.
(When those characteristics are undesirable, use typed arrays instead.)
JavaScript arrays are not associative arrays and so, array elements cannot be
accessed using arbitrary strings as indexes, but must be accessed using
nonnegative integers (or their respective string form) as indexes.
JavaScript arrays are zero-indexed: the first element of an array is at index 0,
the second is at index 1, and so on — and the last element is at the value of
the array's length property minus 1.
JavaScript array-copy operations create shallow copies. (All standard built-in
copy operations with any JavaScript objects create shallow copies, rather
than deep copies).
3.5.3.1 Array indices

3.5.3.2 Relationship between length and numerical


properties
What built-in array methods take into account the value of an array´s length
property when they are called?
A. join(), slice(), indexOf(), etc.
What methods result in updates to an array´s length property?
A. push()., splice()., etc
JS
const fruits = [];
fruits.push("banana", "apple", "peach");
console.log(fruits.length); // 3

How are array´s length property and numerical properties are connected?
A. When setting a property on a JavaScript array when the property is a valid
array index and that index is outside the current bounds of the array, the
engine will update the array's length property accordingly:
JS
fruits[5] = "mango";
console.log(fruits[5]); // 'mango'
console.log(Object.keys(fruits)); // ['0', '1', '2', '5']
console.log(fruits.length); // 6

Increasing the length extends the array by adding empty slots without
creating any new elements — not even undefined.
fruits.length = 10;
console.log(fruits); // ['banana', 'apple', 'peach', empty x 2, 'mango', empty x 4]
console.log(Object.keys(fruits)); // ['0', '1', '2', '5']
console.log(fruits.length); // 10
console.log(fruits[8]); // undefined

Decreasing the length property does, however, delete elements.


fruits.length = 2;
console.log(Object.keys(fruits)); // ['0', '1']
console.log(fruits.length); // 2

3.5.3.3 Array methods and empty slots

Methods Behavior when encountering empty slots


concat(), copyWithin(), every(), filter Have special treatment for empty slots
(), flat(), flatMap(), forEach(), index
Of(), lastIndexOf(), map(), reduce(),
reduceRight(), reverse(), slice(), som
e(), sort(), and splice()
Older like forEach Treat empty slots differently from indices
that contain undefined. This method don
´t visit empty slots at all.
concat, copyWithin Preserve empty slots when doing the
copying, so in the end the array is still
sparse.
Newer methods (e.g. keys) Do not treat empty slots specially and
entries(), fill(), find(), findIndex(), fin treat them as if they contain undefined
dLast(), findLastIndex(), includes(), j
oin(), keys(), toLocaleString(), toRev
ersed(), toSorted(), toSpliced(), valu
es(), and with().

Example of old methods that treat empty slots differently from indices that
contain undefined:
JS
const colors = ["red", "yellow", "blue"];
colors[5] = "purple";
colors.forEach((item, index) => {
console.log(`${index}: ${item}`);
});
// Output:
// 0: red
// 1: yellow
// 2: blue
// 5: purple

colors.reverse(); // ['purple', empty × 2, 'blue', 'yellow', 'red']

Example of newer methods that treat empty slots as if they contain


undefined:
JS
const colors = ["red", "yellow", "blue"];
colors[5] = "purple";
const iterator = colors.keys();
for (const key of iterator) {
console.log(`${key}: ${colors[key]}`);
}
// Output
// 0: red
// 1: yellow
// 2: blue
// 3: undefined
// 4: undefined
// 5: purple

const newColors = colors.toReversed(); // ['purple', undefined, undefined, 'blue',


'yellow', 'red']

3.5.3.4 Copying methods and mutating methods


How non mutating methods performs when copying elements of the original
array and what are examples of these?
A .-
 Objects: the object reference is copied into the new array. Both the
original and new array refer to the same object. That is, if a referenced
object is modified, the changes are visible to both the new and original
arrays.
 Primitive types such as strings, numbers and booleans
(not String, Number, and Boolean objects): their values are copied into
the new array.

Mutating method Non-mutating alternative

copyWithin() No one-method alternative

fill() No one-method alternative

pop() slice(0, -1)

push(v1, v2) concat([v1, v2])

reverse() toReversed()

shift() slice(1)

sort() toSorted()

splice() toSpliced()

unshift(v1, v2) toSpliced(0, 0, v1, v2)


What methods are mutating methods?
Other methods mutate the array that the method was called on, in which
case their return value differs depending on the method: sometimes a
reference to the same array, sometimes the length of the new array.
The following methods create new arrays by
accessing this.constructor[Symbol.species] to determine the constructor to
use: concat(), filter(), flat(), flatMap(), map(), slice(), and splice() (to construct
the array of removed elements that's returned).
The following methods always create new arrays with the Array base
constructor: toReversed(), toSorted(), toSpliced(), and with(). See table
above.
How to change a mutating method into a non-mutating alternative?
A .- By using the spread syntax or slice() to create a copy first:
JS
arr.copyWithin(0, 1, 2); // mutates arr
const arr2 = arr.slice().copyWithin(0, 1, 2); // does not mutate arr
const arr3 = [...arr].copyWithin(0, 1, 2); // does not mutate arr

3.5.3.5 Iterative methods


Many array methods take a callback function as an argument. The callback
function is called sequentially and at most once for each element in the array,
and the return value of the callback function is used to determine the return
value of the method. They all share the same signature:
JS
method(callbackFn, thisArg)

Where callbackFn takes three arguments:


element
The current element being processed in the array.
index
The index of the current element being processed in the array.
array
The array that the method was called upon.
What callbackFn is expected to return depends on the array method that was
called.
The thisArg argument (defaults to undefined) will be used as the this value
when calling callbackFn. The this value ultimately observable by callbackFn is
determined according to the usual rules: if callbackFn is non-strict,
primitive this values are wrapped into objects, and undefined/null is
substituted with globalThis. The thisArg argument is irrelevant for
any callbackFn defined with an arrow function, as arrow functions don't have
their own this binding.
The array argument passed to callbackFn is most useful if you want to read
another index during iteration, because you may not always have an existing
variable that refers to the current array. You should generally not mutate the
array during iteration (see mutating initial array in iterative methods), but you
can also use this argument to do so. The array argument is not the array that
is being built, in the case of methods like map(), filter(), and flatMap() —
there is no way to access the array being built from the callback function.
All iterative methods are copying and generic, although they behave
differently with empty slots.
The following methods are
iterative:every(), filter(), find(), findIndex(), findLast(), findLastIndex(), flatMap
(), forEach(), map(), and some().
In particular, every(), find(), findIndex(), findLast(), findLastIndex(),
and some() do not always invoke callbackFn on every element — they stop
iteration as soon as the return value is determined.
The reduce() and reduceRight() methods also take a callback function and run
it at most once for each element in the array, but they have slightly different
signatures from typical iterative methods (for example, they don't
accept thisArg).
The sort() method also takes a callback function, but it is not an iterative
method. It mutates the array in-place, doesn't accept thisArg, and may invoke
the callback multiple times on an index.
Iterative methods iterate the array like the following (with a lot of technical
details omitted):

JS
function method(callbackFn, thisArg) {
const length = this.length;
for (let i = 0; i < length; i++) {
if (i in this) {
const result = callbackFn.call(thisArg, this[i], i, this);
// Do something with result; maybe return early
}
}
}
Note the following:
1. Not all methods do the i in this test. The find, findIndex, findLast,
and findLastIndex methods do not, but other methods do.
2. The length is memorized before the loop starts. This affects how
insertions and deletions during iteration are handled (see mutating
initial array in iterative methods).
3. The method doesn't memorize the array contents, so if any index is
modified during iteration, the new value might be observed.
4. The code above iterates the array in ascending order of index. Some
methods iterate in descending order of index (for (let i = length - 1; i >=
0; i--)): reduceRight(), findLast(), and findLastIndex().
5. reduce and reduceRight have slightly different signatures and do not
always start at the first/last element.
3.5.3.6 Generic array methods
Array methods are always generic — they don't access any internal data of
the array object. They only access the array elements through
the length property and the indexed elements. This means that they can be
called on array-like objects as well.
JS
const arrayLike = {
0: "a",
1: "b",
length: 2,
};
console.log(Array.prototype.join.call(arrayLike, "+")); // 'a+b'

3.5.3.7 Normalization of the length property

The length property is converted to an integer and then clamped to the range
between 0 and 253 - 1. NaN becomes 0, so even when length is not present or
is undefined, it behaves as if it has value 0.
The language avoids setting length to an unsafe integer. All built-in methods
will throw a TypeError if length will be set to a number greater than 253 - 1.
However, because the length property of arrays throws an error if it's set to
greater than 232 - 1, the safe integer threshold is usually not reached unless
the method is called on a non-array object.
JS
Array.prototype.flat.call({}); // []

Some array methods set the length property of the array object. They always
set the value after normalization, so length always ends as an integer.
JS
const a = { length: 0.7 };
Array.prototype.push.call(a);
console.log(a.length); // 0

3.5.3.8 Array-like objects


The term array-like object refers to any object that doesn't throw during
the length conversion process described above. In practice, such object is
expected to actually have a length property and to have indexed elements in
the range 0 to length - 1. (If it doesn't have all indices, it will be functionally
equivalent to a sparse array.) Any integer index less than zero or greater
than length - 1 is ignored when an array method operates on an array-like
object.
Many DOM objects are array-like -for example, NodeList and HTMLCollection.
The arguments object is also array like. You can call array methods on them
even if they don't have these methods themselves.
JS
function f() {
console.log(Array.prototype.join.call(arguments, "+"));
}

f("a", "b"); // 'a+b'

3.5.4 CONSTRUCTOR
Array()

Creates a new Array object.

3.5.5 STATIC PROPERTIES


Array[@@species]

Returns the Array constructor.

3.5.6 STATIC METHODS

Array.from()
Creates a new Array instance from an iterable or array-like object.
Array.fromAsync()
Creates a new Array instance from an async iterable, iterable, or array-like
object.
Array.isArray()
Returns true if the argument is an array, or false otherwise.
Array.of()
Creates a new Array instance with a variable number of arguments,
regardless of number or type of the arguments.
3.5.7 INSTANCE PROPERTIES
These properties are defined on Array.prototype and shared by
all Array instances.
Array.prototype.constructor
The constructor function that created the instance object.
For Array instances, the initial value is the Array constructor.
Array.prototype[@@unscopables]
Contains property names that were not included in the ECMAScript standard
prior to the ES2015 version and that are ignored for with statement-binding
purposes.
These properties are own properties of each Array instance.
length
Reflects the number of elements in an array.

3.5.8 INSTANCE METHODS

Array.prototype.at()
Returns the array item at the given index. Accepts negative integers, which
count back from the last item.
Array.prototype.concat()
Returns a new array that is the calling array joined with other array(s) and/or
value(s).
Array.prototype.copyWithin()
Copies a sequence of array elements within an array.
Array.prototype.entries()
Returns a new array iterator object that contains the key/value pairs for each
index in an array.
Array.prototype.every()
Returns true if every element in the calling array satisfies the testing function.
Array.prototype.fill()
Fills all the elements of an array from a start index to an end index with a
static value.
Array.prototype.filter()
Returns a new array containing all elements of the calling array for which the
provided filtering function returns true.
Array.prototype.find()
Returns the value of the first element in the array that satisfies the provided
testing function, or undefined if no appropriate element is found.
Array.prototype.findIndex()
Returns the index of the first element in the array that satisfies the provided
testing function, or -1 if no appropriate element was found.
Array.prototype.findLast()
Returns the value of the last element in the array that satisfies the provided
testing function, or undefined if no appropriate element is found.
Array.prototype.findLastIndex()
Returns the index of the last element in the array that satisfies the provided
testing function, or -1 if no appropriate element was found.
Array.prototype.flat()
Returns a new array with all sub-array elements concatenated into it
recursively up to the specified depth.
Array.prototype.flatMap()
Returns a new array formed by applying a given callback function to each
element of the calling array, and then flattening the result by one level.
Array.prototype.forEach()
Calls a function for each element in the calling array.
Array.prototype.includes()
Determines whether the calling array contains a value,
returning true or false as appropriate.
Array.prototype.indexOf()
Returns the first (least) index at which a given element can be found in the
calling array.
Array.prototype.join()
Joins all elements of an array into a string.
Array.prototype.keys()
Returns a new array iterator that contains the keys for each index in the
calling array.
Array.prototype.lastIndexOf()
Returns the last (greatest) index at which a given element can be found in the
calling array, or -1 if none is found.
Array.prototype.map()
Returns a new array containing the results of invoking a function on every
element in the calling array.
Array.prototype.pop()
Removes the last element from an array and returns that element.
Array.prototype.push()
Adds one or more elements to the end of an array, and returns the
new length of the array.
Array.prototype.reduce()
Executes a user-supplied "reducer" callback function on each element of the
array (from left to right), to reduce it to a single value.
Array.prototype.reduceRight()
Executes a user-supplied "reducer" callback function on each element of the
array (from right to left), to reduce it to a single value.
Array.prototype.reverse()
Reverses the order of the elements of an array in place. (First becomes the
last, last becomes first.)
Array.prototype.shift()
Removes the first element from an array and returns that element.
Array.prototype.slice()
Extracts a section of the calling array and returns a new array.
Array.prototype.some()
Returns true if at least one element in the calling array satisfies the provided
testing function.
Array.prototype.sort()
Sorts the elements of an array in place and returns the array.
Array.prototype.splice()
Adds and/or removes elements from an array.
Array.prototype.toLocaleString()
Returns a localized string representing the calling array and its elements.
Overrides the Object.prototype.toLocaleString() method.
Array.prototype.toReversed()
Returns a new array with the elements in reversed order, without modifying
the original array.
Array.prototype.toSorted()
Returns a new array with the elements sorted in ascending order, without
modifying the original array.
Array.prototype.toSpliced()
Returns a new array with some elements removed and/or replaced at a given
index, without modifying the original array.
Array.prototype.toString()
Returns a string representing the calling array and its elements. Overrides
the Object.prototype.toString() method.
Array.prototype.unshift()
Adds one or more elements to the front of an array, and returns the
new length of the array.
Array.prototype.values()
Returns a new array iterator object that contains the values for each index in
the array.
Array.prototype.with()
Returns a new array with the element at the given index replaced with the
given value, without modifying the original array.
Array.prototype[@@iterator]()
An alias for the values() method by default.
3.5.9 EXAMPLES
3.5.9.1 Creating an array
Three ways are shown: first using array literal notation, then using
the Array() constructor, and finally using String.prototype.split() to build the
array from a string.
JS
// 'fruits' array created using array literal notation.
const fruits = ["Apple", "Banana"];
console.log(fruits.length);
// 2

// 'fruits2' array created using the Array() constructor.


const fruits2 = new Array("Apple", "Banana");
console.log(fruits2.length);
// 2

// 'fruits3' array created using String.prototype.split().


const fruits3 = "Apple, Banana".split(", ");
console.log(fruits3.length);
// 2

3.5.9.2 Creating a string from an array


This example uses the join() method to create a string from the fruits array.
JS
const fruits = ["Apple", "Banana"];
const fruitsString = fruits.join(", ");
console.log(fruitsString);
// "Apple, Banana"

3.5.9.3 Accesing an array item by its index


This example shows how to access items in the fruits array by specifying the
index number of their position in the array.
JS
const fruits = ["Apple", "Banana"];

// The index of an array's first element is always 0.


fruits[0]; // Apple
// The index of an array's second element is always 1.
fruits[1]; // Banana

// The index of an array's last element is always one


// less than the length of the array.
fruits[fruits.length - 1]; // Banana

// Using an index number larger than the array's length


// returns 'undefined'.
fruits[99]; // undefined

3.5.9.4 Finding the index of an item in an array

This example uses the indexOf() method to find the position (index) of the
string "Banana" in the fruits array.
JS
const fruits = ["Apple", "Banana"];
console.log(fruits.indexOf("Banana"));
// 1

3.5.9.5 Checking if an array contains a certain item


This example shows two ways to check if the fruits array
contains "Banana" and "Cherry": first with the includes() method, and then
with the indexOf() method to test for an index value that's not -1.
JS
const fruits = ["Apple", "Banana"];

fruits.includes("Banana"); // true
fruits.includes("Cherry"); // false

// If indexOf() doesn't return -1, the array contains the given item.
fruits.indexOf("Banana") !== -1; // true
fruits.indexOf("Cherry") !== -1; // false
3.5.9.6 Append an item to an array

This example uses the push() method to append a new string to


the fruits array.
JS
const fruits = ["Apple", "Banana"];
const newLength = fruits.push("Orange");
console.log(fruits);
// ["Apple", "Banana", "Orange"]
console.log(newLength);
// 3

3.5.9.7 Removing the last item from an array


This example uses the pop() method to remove the last item from
the fruits array.
JS
const fruits = ["Apple", "Banana", "Orange"];
const removedItem = fruits.pop();
console.log(fruits);
// ["Apple", "Banana"]
console.log(removedItem);
// Orange

3.5.9.8 Truncate an array down to just its first N items


This example uses the splice() method to truncate the fruits array down to
just its first 2 items.
JS
const fruits = ["Apple", "Banana", "Strawberry", "Mango", "Cherry"];
const start = 2;
const removedItems = fruits.splice(start);
console.log(fruits);
// ["Apple", "Banana"]
console.log(removedItems);
// ["Strawberry", "Mango", "Cherry"]
3.5.9.9 Removing the first item from an array
This example uses the shift() method to remove the first item from
the fruits array.
JS
const fruits = ["Apple", "Banana"];
const removedItem = fruits.shift();
console.log(fruits);
// ["Banana"]
console.log(removedItem);
// Apple

3.5.9.10 Removing multiple items from the beginning


of an array
This example uses the splice() method to remove the first 3 items from
the fruits array.
JS
const fruits = ["Apple", "Strawberry", "Cherry", "Banana", "Mango"];
const start = 0;
const deleteCount = 3;
const removedItems = fruits.splice(start, deleteCount);
console.log(fruits);
// ["Banana", "Mango"]
console.log(removedItems);
// ["Apple", "Strawberry", "Cherry"]

3.5.9.11 Add a new first item to an array


This example uses the unshift() method to add, at index 0, a new item to
the fruits array — making it the new first item in the array.

const fruits = ["Banana", "Mango"];


const newLength = fruits.unshift("Strawberry");
console.log(fruits);
// ["Strawberry", "Banana", "Mango"]
console.log(newLength);
// 3
3.5.9.12 Removing a single item by index
This example uses the splice() method to remove the string "Banana" from
the fruits array — by specifying the index position of "Banana".
JS
const fruits = ["Strawberry", "Banana", "Mango"];
const start = fruits.indexOf("Banana");
const deleteCount = 1;
const removedItems = fruits.splice(start, deleteCount);
console.log(fruits);
// ["Strawberry", "Mango"]
console.log(removedItems);
// ["Banana"]

3.5.9.13 Removing multiple items by index


This example uses the splice() method to remove the
strings "Banana" and "Strawberry" from the fruits array — by specifying the
index position of "Banana", along with a count of the number of total items
to remove.
JS
const fruits = ["Apple", "Banana", "Strawberry", "Mango"];
const start = 1;
const deleteCount = 2;
const removedItems = fruits.splice(start, deleteCount);
console.log(fruits);
// ["Apple", "Mango"]
console.log(removedItems);
// ["Banana", "Strawberry"]

3.5.9.14 Replacing multiple items in an array


This example uses the splice() method to replace the last 2 items in
the fruits array with new items.
JS
const fruits = ["Apple", "Banana", "Strawberry"];
const start = -2;
const deleteCount = 2;
const removedItems = fruits.splice(start, deleteCount, "Mango", "Cherry");
console.log(fruits);
// ["Apple", "Mango", "Cherry"]
console.log(removedItems);
// ["Banana", "Strawberry"]
3.5.9.15 Iterating over an array
This example uses a for...of loop to iterate over the fruits array, logging each
item to the console.
JS
const fruits = ["Apple", "Mango", "Cherry"];
for (const fruit of fruits) {
console.log(fruit);
}
// Apple
// Mango
// Cherry

3.5.9.16 Calling a function on each element in an array


This example uses the forEach() method to call a function on each element in
the fruits array; the function causes each item to be logged to the console,
along with the item's index number.
JS
const fruits = ["Apple", "Mango", "Cherry"];
fruits.forEach((item, index, array) => {
console.log(item, index);
});
// Apple 0
// Mango 1
// Cherry 2

3.5.9.17 Merging multiple arrays together


This example uses the concat() method to merge the fruits array with
a moreFruits array, to produce a new combinedFruits array. Notice
that fruits and moreFruits remain unchanged.
JS
const fruits = ["Apple", "Banana", "Strawberry"];
const moreFruits = ["Mango", "Cherry"];
const combinedFruits = fruits.concat(moreFruits);
console.log(combinedFruits);
// ["Apple", "Banana", "Strawberry", "Mango", "Cherry"]

// The 'fruits' array remains unchanged.


console.log(fruits);
// ["Apple", "Banana", "Strawberry"]
// The 'moreFruits' array also remains unchanged.
console.log(moreFruits);
// ["Mango", "Cherry"]

3.5.10 Examples of using array methods with


applications to real life
https://dev.to/webdev-mohdamir/master-javascript-array-methods-like-a-
pro-part-1-1f3j
3.5.11 Summary
Declaring:
let scores = [100, 72, 83, 94, 88, 87];
let names = ['Nancy','Blessing','Jorge','Svetlana'];

Arrays are zero-based indexed, meaning the first element is at index 0,


the second element is at index 1, and so on.

Accessing:

Arrays can be accessed by an index reference:

let aScore = scores[0]; // The aScore variable is assigned the value of


100

Modifying:
scores[0] = 99; // This assignment expression
changed the first score in the array from 100 to 99.
Iterating:
for (let i = 0; i < scores.length; i++) {
console.log(scores[i]);
}

Preferred: Arrays can be iterated over using other looping structures


like forEach:
scores.forEach(function(score) {
console.log(score);
});
Length property:
let numScores = scores.length; // The numScores
variable is assigned the value of 6
Array methods

Arrays have a number of methods that can be used to manipulate


(change) them:

scores.push(100); // Adds a new element to the end of the array


scores.pop(); // Removes the last element from the array
scores.shift(); // Removes the first element from the array
scores.unshift(100); // Adds a new element to the beginning of the array
scores.slice(2,3); // Cut out a portion of the array starting at an index
for a given length
scores.splice(2, 1); // Removes 1 element from the array starting at
index 2
scores.join(', '); // transform the array into a single string with a
comma and space delimiter option

3.6 JavaScript Functions


https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions
What is a function in JavaScript?
A .- Functions in JavaScript are common control structures in programming.
They are blocks of code that can be called by name to perform a specific task.
Functions can be called multiple times throughout a program. Functions can
also be passed data to work with, and can return data back to the caller.
"Functions are one of the fundamental building blocks in JavaScript. A
function in JavaScript is similar to a procedure—a set of statements that
performs a task or calculates a value, but for a procedure to qualify as a
function, it should take some input and return an output where there is some
obvious relationship between the input and the output. To use a function,
you must define it somewhere in the scope from which you wish to call it.
- MDN web docs"
How to define functions?
How to call functions?
3.6.1 Defining functions
3.6.1.1 Function declarations

A function definition (also called a function declaration, or function


statement) consists of the function keyword, followed by:
 The name of the function.
 A list of parameters to the function, enclosed in parentheses and
separated by commas.
 The JavaScript statements that define the function, enclosed in curly
braces, { /* … */ }.
For example, the following code defines a simple function named square:
JS
function square(number) {
return number * number;
}
The function square takes one parameter, called number. The function
consists of one statement that says to return the parameter of the function
(that is, number) multiplied by itself. The return statement specifies the value
returned by the function, which is number * number.
How the parameter of a function are processed and what is the scope of the
statement?
Type of parameter Example
A value Parameters are
essentially passed to
functions by value — so
if the code within the
body of a function
assigns a completely
new value to a
parameter that was
passed to the
function, the change is
not reflected globally
or in the code which
called that function.
An object if the function changes function
myFunc(theObject) {
the object's properties, theObject.make =
that change is visible "Toyota";
}
outside the function, as
shown in the following const mycar = {
make: "Honda",
example: model: "Accord",
year: 1998,
};

console.log(mycar.make); /
/ "Honda"
myFunc(mycar);
console.log(mycar.make); /
/ "Toyota"

An array if the function changes function myFunc(theArr) {


theArr[0] = 30;
any of the array's }
values, that change is
const arr = [45];
visible outside the
function, as shown in console.log(arr[0]); // 45
myFunc(arr);
the following example: console.log(arr[0]); // 30

3.6.1.2 Function expressions


Functions can also be created by a function expression.
What is a function expression?
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
Operators/function
How can the function square be written anonymously?
JS
function square(number) {
return number * number;
}

As follows:
const square = function (number) {
return number * number;
};

console.log(square(4)); // 16

What are the advantages of providing a name to a function expression?


A .- . Providing a name allows the function to refer to itself, and also makes it
easier to identify the function in a debugger's stack traces:
const factorial = function fac(n) {
return n < 2 ? 1 : n * fac(n - 1);
};

console.log(factorial(3)); // 6

When are functions expressions convenient?


A .- Function expressions are convenient when passing a function as an
argument to another function. The following example shows a map function
that should receive a function as first argument and an array as second
argument:
function map(f, a) {
const result = new Array(a.length);
for (let i = 0; i < a.length; i++) {
result[i] = f(a[i]);
}
return result;
}

In the following code, the function receives a function defined by a function


expression and executes it for every element of the array received as a
second argument:
function map(f, a) {
const result = new Array(a.length);
for (let i = 0; i < a.length; i++) {
result[i] = f(a[i]);
}
return result;
}

const cube = function (x) {


return x * x * x;
};
const numbers = [0, 1, 2, 5, 10];
console.log(map(cube, numbers)); // [0, 1, 8, 125, 1000]

How can a function be defined based on a condition?


A .- For example, the following function definition defines myFunc only
if num equals 0:

let myFunc;
if (num === 0) {
myFunc = function (theObject) {
theObject.make = "Toyota";
};
}
3.6.2 Calling functions
What is calling functions?
It is executing the code inside a defined function, it is performing the
specified actions of a function with the indicated parameters.
How to call the function below?
function square(number) {

return number * number;

It is called as follows:
square(5);
It calls the function with an argument of 5. The function executes its
statements and returns the value of 25.
How is the scope of a function declaration defined?
A .- The scope of a function declaration is the function in which it is declared
(or the entire program, if it is declared at the top level).
How can a function call itself?
A .- A function can call itself. For example, here is a function that computes
factorials recursively:
function factorial(n) {
if (n === 0 || n === 1) {
return 1;
} else {
return n * factorial(n - 1);
}
}

You could then compute the factorials of 1 through 5 as follows:

console.log(factorial(1)); // 1
console.log(factorial(2)); // 2
console.log(factorial(3)); // 6
console.log(factorial(4)); // 24
console.log(factorial(5)); // 120

3.6.2.1 Function hoisting


What is function hoisting?
It is executing functions despite the calling was made before the declaration
of the function, see the examples below:
console.log(square(5)); // 25

function square(n) {
return n * n;
}
This code runs without any error, despite the square() function being called
before it's declared. This is because the JavaScript interpreter hoists the
entire function declaration to the top of the current scope, so the code above
is equivalent to:
// All function declarations are effectively at the top of the scope
function square(n) {
return n * n;
}

console.log(square(5)); // 25

Function hosting only works with function declarations – not with function
expressions. The following code won´t work:
console.log(square(5)); // ReferenceError: Cannot access 'square' before initialization
const square = function (n) {
return n * n;
};
3.6.3 Function scope
Kind of function Scope
Function defined in the global scope It can access all variables defined in
the global scope.
Function defined inside another I can access all variables defined in its
function parent function, and any other
variables to which the parent
function has access.

Example:
// The following variables are defined in the global scope
const num1 = 20;
const num2 = 3;
const name = "Chamakh";

// This function is defined in the global scope


function multiply() {
return num1 * num2;
}

console.log(multiply()); // 60

// A nested function example


function getScore() {
const num1 = 2;
const num2 = 3;

function add() {
return `${name} scored ${num1 + num2}`;
}

return add();
}

console.log(getScore()); // "Chamakh scored 5"

In the example above, function multipy () {} has a global equal to function


getScore. The function add is defined inside the getScore function.
3.6.4 Scope and the function stack
How can a function refer to itself?
A .-
3.6.5 Closures
3.6.6 Using the arguments object
3.6.7 Function parameters

3.6.8 Arrow functions

What is this is functions?


The this keyword refers to the context where a piece of code, such as a
function's body, is supposed to run. Most typically, it is used in object
methods, where this refers to the object that the method is attached to, thus
allowing the same method to be reused on different objects.
The value of this in JavaScript depends on how a function is invoked
(runtime binding), not how it is defined. When a regular function is invoked
as a method of an object (obj.method()), this points to that object. When
invoked as a standalone function (not attached to an
object: func()), this typically refers to the global object (in non-strict mode)
or undefined (in strict mode). The Function.prototype.bind() method can
create a function whose this binding doesn't change, and
methods apply() and call() can also set the this value for a particular call.
Arrow functions differ in their handling of this: they inherit this from the
parent scope at the time they are defined. This behavior makes arrow
functions particularly useful for callbacks and preserving context. However,
arrow functions do not have their own this binding. Therefore, their this value
cannot be set by bind(), apply() or call() methods, nor does it point to the
current object in object methods.
JS
const test = {
prop: 42,
func: function () {
return this.prop;
},
};

console.log(test.func());
// Expected output: 42

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
Operators/this

Check Your Understanding


Given the following code snippet:
let firstName = 'Antonia';
let lastName = 'Francesca';
Write a function declaration / definition named fullName that has two
parameters named first and last. The function's purpose is to combine those
two string parameters together to return one combined string (a 'full' name)
with a space between the first and last variables.
function fullName(first, last) {
const name= `${first} +${last}`;
return name;
}
Now use an anonymous function expression to do the same thing where the
function is assigned to a variable named fullName.
const fullName = function(first, last) {
const name= `${first} +${last}`;
return name;
}
Now use an arrow function expression to do the same thing where the
function is assigned to a variable named fullName.
Const fullName = (firstName, lastName) => `${firstName} +${lastN}`;

Write an expression that calls the fullName function declaration and writes
the result to an existing HTML element's text node with the ID of fullName

fullName(Carlos, Medina);
document.querySelector('#fullName').innerHTML =
fullName(firstName, lastName);

3.7 Evaluation
A student has this code for their responsive image. What feedback would
you give them?
Check all the apply.

<picture>
<source srcset="images/hero-small.webp" media="(max-width: 500px)">
<source srcset="images/hero-medium.webp" media="(max-width: 1000px)">
<img srcset="images/hero-large.webp" alt="Hero Photo" width="500"
height="250">
</picture>

You have the two source element lines backwards.

You forgot to add the units (px) to the width and height attribute values.
You are not allowed to use max-width with the <source> element's
media attribute.

Your source references are missing alt attributes.

Good job, the code looks good.

Question 4
1 / 1 pts
One of your peers is confused as to why these JavaScript statements do
not work as intended. They report that when a valid chapter is entered
into the HTML input field with an id of "favchap" the message on the
screen is wrong saying that the favorite chapter is something like [object
HTMLInputElement]. And when they do not enter anything into the input
field, the message is still outputting the "Thank you. your favorite
chapter is [object HTMLInputElement]".
What advice would you give them?
Check all the apply.

const message = document.querySelector('#message');


const input = document.querySelector('#favchap');
if (input !== "") {
message.innerHTML = `Thank you. Your favorite chapter is ${input}.`;
} else {
message.innerHTML = `Please enter a chapter.`;
}

The HTML input element must have an id of "input" to match the


variable identifier used.

Reference the value property of the #favchap input element, not just
the element.

Template literal strings (`...`) cannot be used to produce output to the


screen.
Use single quotes and not double quotes in the if block condition.

Question 5
1 / 1 pts
Another student has reviewed your favorite chapter application and
commented that you must use innerHTML versus textContent when
providing the list item's content.

li.innerHTML = item;

versus

li.textContent = item;

What would be your reply to them?


Mark all that apply.

Using the textContent property is the only option when working with
HTML list item content.

Actually, using innerText would be the best option in this case.

Either property will work in this case given that the item variable is a
simple string.

That would be true if the item variable contained HTML tags.

Question 6
1 / 1 pts
JavaScript uses type conversion to coerce any value to a Boolean in
contexts that require it, such as conditionals and loops. A falsy value is
a value that is considered false when encountered in a Boolean context.
Which of the following are JavaScript falsy values?

NaN (not a number)


"0"

undefined

null

"False"

'', "", or ``

999

Question 7
1 / 1 pts
Which of the following methods can be used to add elements to the end
of an array in JavaScript?

add()

unshift()

spice()

push()
Question 8
1 / 1 pts
Given the following code snippet, which of the following is the output to
the console?

let scores = [100, 72, 83, 94, 88, 87];


let accumulator = 0;
let count = 0;
scores.forEach(score => {
if (score > 87) {
accumulator += score;
count ++;
}
});
if ( count > 0 ) {
console.log(accumulator/count);
} else {
console.log("No scores reported.");
}

94

92.25

No scores reported.

87.5

Question 9
1 / 1 pts
Which of the following code expressions produces the last element
(index) of any array?

array.lastIndex()

array.lastIndex
array.length

array.length - 1

Question 10
1 / 1 pts
Rewrite (refactor) this function declaration by using an arrow function
instead of a function declaration.

function fullName(first, last) {


return `${first} ${last}`;
}

const fullName = (first, last) => `${first} ${last}`;

const fullName = function (first, last) { `${first} ${last}`;}

function = first + " " + last`

const generateFullName = (first, last) {first.concat(' ', last);}

Question 11
1 / 1 pts
In a JavaScript function declaration, which of the following is the keyword
used to declare a function?

function

func

functionBlock
def

Question 12
1 / 1 pts
Finish this statement.
The pseudo-class is useful for declaring global CSS
variables and represents the <html> element and is identical to the
selector html, except that its specificity is higher.

global

root

html

specific

Question 13
1 / 1 pts
Which of the following statements regarding pseudo-elements in CSS is
correct?

Pseudo-elements allow you to create virtual elements that do not exist


in the HTML document.

Pseudo-elements are used to style elements based on their position in


the document tree.

Pseudo-elements are represented by double colons (::) and are used to


style specific parts of an element.
Pseudo-elements are used to select and style elements based on their
attributes.

Foto de Lyon Peru: https://www.pexels.com/es-es/foto/coches-punto-de-referencia-


viaje-viajar-21637495/

Foto de Lyon Peru: https://www.pexels.com/es-es/foto/coches-punto-de-referencia-


viaje-viajar-21637495/

Foto de Matan Levanon en Unsplash


Foto de Javier Collarte en Unsplash
Foto de Leonardo Rossatti: https://www.pexels.com/es-es/foto/salar-de-uyuni-
2613110/

Chapter 4 HTML TABLES- Lazyloading images – JavaScript


Objects – JavaScript Array Functions
4.1 Website Project:

The objective of the website project is to support the course learning


outcomes.
1. Develop responsive web pages that follow best practices and use valid
HTML and CSS.
2. Demonstrate proficiency with JavaScript language syntax.
3. Use JavaScript to respond to events and dynamically modify HTML.
4. Demonstrate the traits of an effective team member (such as clear
communication, collaboration, fulfilling assignments, and meeting
deadlines).
4.1.1 Project description

The final website project is a comprehensive assessment of the course


learning outcomes giving you an opportunity to demonstrate your mastery of
the course learning outcomes in HTML, CSS, and JavaScript to create a
dynamic and responsive website that adheres to development standards.
This project will be of your own design and development. You may not
consult nor work with any other individual nor group on the project. The
content and subject is driven from your proposal of a topic and the site
should be complete without any placeholders. The images and brief verbiage
may be referenced from other sources which will need to be cited in a
resource reference/attributions page, which link will be located in the footer.
This attributions page does not need to be styled.
Project requirements
Your project must meet the following functional and developmental
specifications:
These are the minimum specifications for the project. You are encouraged to
go above and beyond these requirements to demonstrate your mastery of
the course learning outcomes.
1. Your website project must be hosted on GitHub and rendered via
GitHub Pages.
2. The website must consist of at least three (3) congruent pages with a
common navigation and theme that appeals to the target audience.
3. The site must have significant and relevant content that supports the
purpose of the site as outlined in your website plan.
4. The design must support accessibility, usability, visual appeal, and
design principles.
5. Structure the pages with valid, standards-based HTML markup.
6. Style the site with valid CSS that does not contain unused and
unnecessary (duplicate) declarations and rules.
7. Style the site so that it is responsive to mobile (portrait and landscape)
and larger screen views without violating PARC design principles.
8. All images must be optimized.
9. Use a lazy loading technique to support progressive design.
10.Use an HTML form that meets the standards presented in the course.
11.The site should have dynamic elements provided by Javascript, your
code should show elements of the following application:
o Show some level of organization. At a minimum it should have
more than one function.
o Include DOM interaction: select an element, modify it, and listen
for and react to events.
o Use conditional branching.
o Use objects, arrays, and array methods.
o Exclusively use template literals when building strings.
o Use localStorage.
12.Ensure that there are no spelling or grammatical errors.
13.Complete the project by the due date.
This is a web course intended to help you learn how to construct dynamic and
responsive websites using the core web technologies of contemporary HTML,
CSS, and JavaScript. Third party templates are NOT allowed. Pages built from
site builder software or drag-and-drop tools or that are based on existing sites
are not allowed and will lead to no credit on the term project.
Testing
1. Use the browser's DevTools to check for JavaScript runtime errors in
the console or click the red, error icon in the upper right corner of
DevTools.
2. Use DevTools CSS Overview to check your color contrast.
3. Generate the DevTools Lighthouse report and run diagnostics
for Performance, Accessibility, Best Practices, and SEO in both the
mobile and Desktop views.
4.2 HTML Tables for data presentation
Why is it not a good practice using HTML table structure for site layout?
A. – They are not ideal for responsive behavior.
The markup becomes bloaded and bloaded markup becomes hard to
read, maintain and debug.
When they are not used for the intended purpose but for layout its
accessibility is reduced for the visually impaired.
4.2.1 HTML Advanced features and
accessibility
4.2.1.1 Adding a caption to your table with <caption>
Where is the <caption> tag located?
A. – Just after the opening tag <table>.
HTML
<table>
<caption>
Dinosaurs in the Jurassic period
</caption>


</table>

Example:
HTML & CSS
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>School timetable</title>
<style>
html {
font-family: sans-serif;
}

table {
border-collapse: collapse;
border: 2px solid rgb(200,200,200);
letter-spacing: 1px;
font-size: 0.8rem;
}

td, th {
border: 1px solid rgb(190,190,190);
padding: 10px 20px;
}

td {
text-align: center;
}

caption {
padding: 10px;
}
</style>
</head>
<body>
<h1>School timetable</h1>

<table>
<caption>School schedule</caption>
<colgroup>
<col span="2">
<col style="background-color:#97DB9A;">
<col style="width:42px;">
<col style="background-color:#97DB9A;">
<col style="background-color:#DCC48E; border:4px solid #C1437A;">
<col span="2" style="width:42px;">
</colgroup>
<tr>
<td>&nbsp;</td>
<th>Mon</th>
<th>Tues</th>
<th>Wed</th>
<th>Thurs</th>
<th>Fri</th>
<th>Sat</th>
<th>Sun</th>
</tr>
<tr>
<th>1st period</th>
<td>English</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>German</td>
<td>Dutch</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<th>2nd period</th>
<td>English</td>
<td>English</td>
<td>&nbsp;</td>
<td>German</td>
<td>Dutch</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<th>3rd period</th>
<td>&nbsp;</td>
<td>German</td>
<td>&nbsp;</td>
<td>German</td>
<td>Dutch</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<th>4th period</th>
<td>&nbsp;</td>
<td>English</td>
<td>&nbsp;</td>
<td>English</td>
<td>Dutch</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
</table>

</body>
</html>
4.2.1.2 Adding structure with <thead>, <tbody>, and
<tfoot>
What do the <thead>, <tbody>, and <tfoot> tags allow?
A. They allow to mark up a header, body and footer section for the table.
What is the advantage of using these tags?
A. They are very useful for layout and styling the table with CSS acting as
hooks.
What is the order to include these elements?
A.
 The <thead> element must wrap the part of the table that is the
header — this is usually the first row containing the column headings,
but this is not necessarily always the case. If you are
using <col>/<colgroup> elements, the table header should come just
below those.
 The <tbody> element needs to wrap the main part of the table content
that isn't the table header or footer.
 The <tfoot> element needs to wrap the part of the table that is the
footer — this might be a final row with items in the previous rows
summed, for example.

Example:
HTML & CSS
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>My spending record</title>
<link href="minimal-table.css" rel="stylesheet" type="text/css">
<style>
html {
font-family: sans-serif;
}
table {
border-collapse: collapse;
border: 2px solid rgb(200,200,200);
letter-spacing: 1px;
font-size: 0.8rem;
}

td, th {
border: 1px solid rgb(190,190,190);
padding: 10px 20px;
}

th {
background-color: rgb(235,235,235);
}

td {
text-align: center;
}

tr:nth-child(even) td {
background-color: rgb(250,250,250);
}

tr:nth-child(odd) td {
background-color: rgb(245,245,245);
}

caption {
padding: 10px;
}
tbody {
font-size: 95%;
font-style: italic;
}

tfoot {
font-weight: bold;
}
</style>
</head>
<body>
<h1>My spending record</h1>
<table>
<caption>How I chose to spend my money</caption>
<thead>
<tr>
<th>Purchase</th>
<th>Location</th>
<th>Date</th>
<th>Evaluation</th>
<th>Cost (€)</th>
</tr>
</thead>
<tfoot>
<tr>
<td colspan="4">SUM</td>
<td>118</td>
</tr>
</tfoot>
<tbody>
<tr>
<td>Haircut</td>
<td>Hairdresser</td>
<td>12/09</td>
<td>Great idea</td>
<td>30</td>
</tr>
<tr>
<td>Lasagna</td>
<td>Restaurant</td>
<td>12/09</td>
<td>Regrets</td>
<td>18</td>
</tr>
<tr>
<td>Shoes</td>
<td>Shoeshop</td>
<td>13/09</td>
<td>Big regrets</td>
<td>65</td>
</tr>
<tr>
<td>Toothpaste</td>
<td>Supermarket</td>
<td>13/09</td>
<td>Good</td>
<td>5</td>
</tr>
</tbody>

</table>

</body>
</html>

Before applying <thead>, <tbody>, and <tfoot> and applying CSS to them this
is how the tabled looked:
4.2.1.3 Nesting tables
The following markup shows a simple nested table:
HTML
<table id="table1">
<tr>
<th>title1</th>
<th>title2</th>
<th>title3</th>
</tr>
<tr>
<td id="nested">
<table id="table2">
<tr>
<td>cell1</td>
<td>cell2</td>
<td>cell3</td>
</tr>
</table>
</td>
<td>cell2</td>
<td>cell3</td>
</tr>
<tr>
<td>cell4</td>
<td>cell5</td>
<td>cell6</td>
</tr>
</table>

The output of which looks something like this:


4.2.1.4 Table for visually impaired users

What is the proper markup to make programmatic associations additional to


visual for visually impaired users?
Since visually impaired users use screen readers we have to follow the
techniques below for making tables as accessible as possible:
Using column and row headers
Screen readers will identify all headers and use them to make programmatic
associations between those headers and the cells they relate to. The
combination of column and row headers will identify and interpret the data in
each cell so that screen reader users can interpret the table similarly to how a
sighted user does.
We already covered headers in our previous article — see Adding headers
with <th> elements.
The scope attribute
A new topic for this article is the scope attribute, which can be added to
the <th> element to tell screen readers exactly what cells the header is a
header for — is it a header for the row it is in, or the column, for example?
Looking back to our spending record example from earlier on, you could
unambiguously define the column headers as column headers like this:
HTML
<thead>
<tr>
<th scope="col">Purchase</th>
<th scope="col">Location</th>
<th scope="col">Date</th>
<th scope="col">Evaluation</th>
<th scope="col">Cost (€)</th>
</tr>
</thead>

And each row could have a header defined like this (if we added row headers
as well as column headers):
HTML
<tr>
<th scope="row">Haircut</th>
<td>Hairdresser</td>
<td>12/09</td>
<td>Great idea</td>
<td>30</td>
</tr>

Screen readers will recognize markup structured like this, and allow their
users to read out the entire column or row at once, for example.
scope has two more possible values — colgroup and rowgroup. These are
used for headings that sit over the top of multiple columns or rows. If you
look back at the "Items Sold August 2016" table at the start of this section of
the article, you'll see that the "Clothes" cell sits above the "Trousers",
"Skirts", and "Dresses" cells. All of these cells should be marked up as headers
(<th>), but "Clothes" is a heading that sits over the top and defines the other
three subheadings. "Clothes" therefore should get an attribute
of scope="colgroup", whereas the others would get an attribute
of scope="col":
html
<thead>
<tr>
<th colspan="3" scope="colgroup">Clothes</th>
</tr>
<tr>
<th scope="col">Trousers</th>
<th scope="col">Skirts</th>
<th scope="col">Dresses</th>
</tr>
</thead>

The same applies to headers for multiple grouped rows. Take another look at
the "Items Sold August 2016" table, this time focusing on the rows with the
"Amsterdam" and "Utrecht" headers (<th>). You'll notice that the "The
Netherlands" header, also marked up as a <th> element, spans both rows,
being the heading for the other two subheadings.
Therefore, scope="rowgroup" should be specified on this header cell to help
screen readers create the correct associations:
HTML
<tr>
<th rowspan="2" scope="rowgroup">The Netherlands</th>
<th scope="row">Amsterdam</th>
<td>89</td>
<td>34</td>
<td>69</td>
</tr>
<tr>
<th scope="row">Utrecht</th>
<td>80</td>
<td>12</td>
<td>43</td>
</tr>

The id and headers attributes


An alternative to using the scope attribute is to use id and headers attributes
to create associations between headers and cells.
The headers attribute takes a list of unordered, space-separated strings, each
corresponding to the unique id of the <th> elements that provide headings
for either a data cell (<td> element) or another header cell (<th> element).
This gives your HTML table an explicit definition of the position of each cell in
the table, defined by the header(s) for each column and row it is part of, kind
of like a spreadsheet. For it to work well, the table really needs both column
and row headers.
Returning to our "Items Sold August 2016" example, we can use
the id and headers attributes as follows:
1. Add a unique id to each <th> element in the table.
2. Add a headers attribute to each <th> element that acts as a
subheading, i.e., has a header element above it. The value is the id of
the heading that sits over the top and defines the subheadings, which
is "clothes" for the column headers and "belgium" for the row header
in our example.
3. Add a headers attribute to each <td> element and add the ids of the
associated <th> element(s) in form of a space-separated list. You can
proceed as you would in a spreadsheet: Find the data cell and search
for the corresponding headings for the row and column. The order of
the specified ids doesn't matter, but you should be consistent to keep it
organized.
HTML
<thead>
<tr>
<th id="clothes" colspan="3">Clothes</th>
</tr>
<tr>
<th id="trousers" headers="clothes">Trousers</th>
<th id="skirts" headers="clothes">Skirts</th>
<th id="dresses" headers="clothes">Dresses</th>
</tr>
</thead>
<tbody>
<tr>
<th id="belgium" rowspan="3">Belgium</th>
<th id="antwerp" headers="belgium">Antwerp</th>
<td headers="antwerp belgium clothes trousers">56</td>
<td headers="antwerp belgium clothes skirts">22</td>
<td headers="antwerp belgium clothes dresses">43</td>
</tr>
</tbody>

4.2.2 Example of zebra striping style for table


The example can be found in my codepen: https://codepen.io/Carlos-
Manuel-Medina-Sullca/pen/abgoQwB
More about this and other styles can be found here:
https://adrianroselli.com/2017/11/a-responsive-accessible-
table.html#GeneralStylesZebra

4.3 Lazyloading Images

The load of a page can be enhanced by applying a design pattern called


progressive loading or lazy- loading.
This pattern consists of loading the content according to the need, e.g. when
the user scrolls down the page or navigates the coming images and content
will be loaded
The progressive loading is very important because if it takes too long to load
the page the user will leave. Progressive loading is all about deferring loading
of as much of html, css and javascript as possible in order to load those
resources essential for the first glance.
What is the method to defer loading of images?
A. The method is using the attribute loading with the value “lazy”.
<img src="images/anyphoto.jpg" alt="A good
description of the non decorative image"
loading="lazy" width="300" height="500">
The loading attribute has only two states, lazy and eager. The eager value
instructs the browser to render the resource immediately and is the default.
The lazy attribute will defer loading the element, such as
an <img> or <iframe>, until the element is called into view by some user
action, such as scrolling.
"Lazy loading is a strategy to identify resources as non-blocking (non-critical)
and load these only when needed. It's a way to shorten the length of
the critical rendering path, which translates into reduced page load times.
Lazy loading can occur on different moments in the application, but it
typically happens on some user interactions such as scrolling and navigation."
– MDN
Resources to read and learn:
https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading
4.3.1 Activity

1. Activity Instructions
Build a small page with multiple images to scroll through as they are stacked
on top of each other on a single page. When testing the page in a browser,
the images will only load until they come into view. This is difficult to notice
without carefully scrolling and viewing the network tab loading information in
Dev Tools. Here is an example:
Demonstration of browser-level lazy loading support.
2. In VS Code, go to your course wdd131 repo and create a new HTML
page named "lazyload.html" in a "week03" sub folder of wdd131.
3. Support this new page with an external CSS and a JavaScript file that
are each stored in their appropriately named folders within the week03
folder.
4. The lazyload.html page should have a standard <head> and
a <body> and the body should have a <header>, <main>, and <footer>.
5. The header should contain a page title in an <h1> element.
6. The main section contains six (6) <img> child elements
7. The footer can contain whatever you think appropriate along with the
date that the document was last modified using JavaScript.
8. The images dimensions must be 400px width by 600px+ height
(portrait layouts).
Use your own images or external placeholders.
9. Display the <img> elements in one column down the center of the
page regardless of the screen size. (HINT: CSS display:block)
10.Correctly apply native lazy loading to the images so that they only load
when the user scrolls down the page.
11.Add a fade from black animation to each image using CSS animation
and opacity.

4.4 JavaScript Objects


What are JavaScript Objects?
A. They are a way to group related data and functions together.
"An object is a collection of related data and/or functionality. These usually
consist of several variables and functions (which are called properties and
methods when they are inside objects)." - MDN Web Docs
Example of an object representing a person:
let person = {
name: "Antonia Francesca",
age: 30,
profession: "Software Engineer",
hobbies: ["reading", "playing guitar", "hiking"],
address: {
street: "123 Camino Real",
city: "Santa Rosa",
country: "Honduras"
},
isEmployed: true,
greet: function() {
console.log(`Hello, my name is ${this.name}.`);
}
};

What are the properties of the object in the example above?


A. In this example, the person object has various properties such as name,
age, profession, hobbies, address, and isEmployed.
What methods does the example contain?
A. It also includes a greet method that logs a greeting message to the console
using the person's name.
What property is an object itself and what are its properties?
A. The address property is an object itself, containing nested properties such
as street, city, and country.
How can I access and modify the properties of an object and invoke
methods?
A. You can access and modify the properties and invoke the methods of the
person object using dot notation or bracket notation. For example:
console.log(person.hobbies[0]); // Output: reading

Starting with the example below more examples are shown:


const person = {
name: ["Bob", "Smith"],
age: 32,
bio: function () {
console.log(`${this.name[0]} ${this.name[1]} is ${this.age} years old.`);
},
introduceSelf: function () {
console.log(`Hi! I'm ${this.name[0]}.`);
},
};

Accessing with:
person.name;
person.name[0];
person.age;
person.bio();
// "Bob Smith is 32 years old."
person.introduceSelf();
// "Hi! I'm Bob."
4.4.1 JavaScript objects basics
https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics
What is the syntax of JS objects?
A.- The syntax is:
const objectName = {
member1Name: member1Value,
member2Name: member2Value,
member3Name: member3Value,
};

Each member’s name and value are separated by a coma.


The value of a member can be almost anything, from a number, an array or
functions.
How are variables and functions inside of an object named?
A.- A variable is named property.
A function is named method.
In the example bellow we will find two properties and two methods:
const person = {
name: ["Bob", "Smith"],
age: 32,
bio: function () {
console.log(`${this.name[0]} ${this.name[1]} is ${this.age} years old.`);
},
introduceSelf: function () {
console.log(`Hi! I'm ${this.name[0]}.`);
},
};

What is a shorter syntax for writing objects members that are functions?
A.- The object´s members bio and introduceSelf can be written as follows:
const person = {
name: ["Bob", "Smith"],
age: 32,
bio() {
console.log(`${this.name[0]} ${this.name[1]} is ${this.age} years old.`);
},
introduceSelf() {
console.log(`Hi! I'm ${this.name[0]}.`);
},
};

What is an object literal?


A.- It is an object that has functions written in the shorter way.
4.4.1.1 Dot notation
What is useful dot notation for?
A.- It is used to access the members values of properties or functions inside
an object:
Kind of object member Dot notation
Property person.age;
Method person.bio();

How can properties be written as objects inside an object and how dot
notation is used in this case?
A.- The name property as property has to be changed from this
const person = {
name: ["Bob", "Smith"],
};

To this:
const person = {
name: {
first: "Bob",
last: "Smith",
},
// …
};

And now dot notation changes as follows:


person.name.first;
person.name.last;
4.4.1.2 Bracket notation
How is bracket notation used as an alternative to dot notation?
A.- See the example bellow:
Dot notation Bracket notation
person.age; person["age"];

person.name.first; person["name"]["first"];

This looks very similar to how you access the items in an array, and it is
basically the same thing — instead of using an index number to select an
item, you are using the name associated with each member's value. It is no
wonder that objects are sometimes called associative arrays — they map
strings to values in the same way that arrays map numbers to values.

What are some cases in which bracket notation is preferred instead of dot
notation?
A.- If an object property name is held in a variable, then you can't use dot
notation to access the value, but you can access the value using bracket
notation.
In the example below, the logProperty() function can
use person[propertyName] to retrieve the value of the property named
in propertyName.
JS
const person = {
name: ["Bob", "Smith"],
age: 32,
};

function logProperty(propertyName) {
console.log(person[propertyName]);
}

logProperty("name");
// ["Bob", "Smith"]
logProperty("age");
// 32

4.4.1.3 Setting object members


How can the values of a member object be updated with dot or bracket
notation?
A.- By declaring the member you want to set (using dot or bracket notation),
like this:
person.age = 45;
person["name"]["last"] = "Cratchit";

How can new members be created inside an object?


A.- By writing the code as follows:
person["eyes"] = "hazel";
person.farewell = function () {
console.log("Bye everybody!");
};

How can bracket notation can be used to set no only members values
dynamically, but members names too?
A.- Let's say we wanted users to be able to store custom value types in their
people data, by typing the member name and value into two text inputs. We
could get those values like this:
JS
const myDataName = nameInput.value;
const myDataValue = nameValue.value;

We could then add this new member name and value to the person object
like this:
person[myDataName] = myDataValue;
Adding a property to an object using the method above isn't possible with
dot notation, which can only accept a literal member name, not a variable
value pointing to a name.
4.4.1.4 What is this?

The this keyword typically refers to the current object the code is being
executed in. In the context of an object method, this refers to the object that
the method was called on.
Let's illustrate what we mean with a simplified pair of person objects:
JS
const person1 = {
name: "Chris",
introduceSelf() {
console.log(`Hi! I'm ${this.name}.`);
},
};

const person2 = {
name: "Deepti",
introduceSelf() {
console.log(`Hi! I'm ${this.name}.`);
},
};

In this case, person1.introduceSelf() outputs "Hi! I'm


Chris."; person2.introduceSelf() outputs "Hi! I'm Deepti." This happens
because when the method is called, this refers to the object on which the
method is called, which allows the same method definition to work for
multiple objects.
4.4.1.5 Introducing constructors

Using object literals is fine when you only need to create one object, but if
you have to create more than one, as in the previous section, they're
seriously inadequate. We have to write out the same code for every object
we create, and if we want to change some properties of the object - like
adding a height property - then we have to remember to update every object.
We would like a way to define the "shape" of an object — the set of methods
and the properties it can have — and then create as many objects as we like,
just updating the values for the properties that are different.
The first version of this is just a function:
function createPerson(name) {
const obj = {};
obj.name = name;
obj.introduceSelf = function () {
console.log(`Hi! I'm ${this.name}.`);
};
return obj;
}

This function creates and returns a new object each time we call it. The
object will have two members:
 a property name
 a method introduceSelf().
Note that createPerson() takes a parameter name to set the value of
the name property, but the value of the introduceSelf() method will be the
same for all objects created using this function. This is a very common pattern
for creating objects.
Now we can create as many objects as we like, reusing the definition:
const salva = createPerson("Salva");
salva.introduceSelf();
// "Hi! I'm Salva."

const frankie = createPerson("Frankie");


frankie.introduceSelf();
// "Hi! I'm Frankie."

This works fine but is a bit long-winded: we have to create an empty object,
initialize it, and return it. A better way is to use a constructor. A constructor is
just a function called using the new keyword. When you call a constructor, it
will:
 create a new object
 bind this to the new object, so you can refer to this in your constructor
code
 run the code in the constructor
 return the new object.
Constructors, by convention, start with a capital letter and are named for the
type of object they create. So we could rewrite our example like this:
function Person(name) {
this.name = name;
this.introduceSelf = function () {
console.log(`Hi! I'm ${this.name}.`);
};
}

To call Person() as a constructor, we use new:


const salva = new Person("Salva");
salva.introduceSelf();
// "Hi! I'm Salva."

const frankie = new Person("Frankie");


frankie.introduceSelf();
// "Hi! I'm Frankie."
4.4.2 Objects – Representing data

In these examples it is shown how to store data of medications for a user to


access the information like the name, the amount, the unique code of it, and
the expiration date. First it is shown a way using arrays and next, a way using
objects. The pross and cons are mentioned.
Using arrays
First approach

let names = ['Lactated


Ringers','levothyroxine','rosuvastatin','
albuterol','esomeprazole']
let amounts =
['100L','2000ct','1500ct','1325ct','23145
ct']
let codes =
['13ab7','at342','gr5423','iuy6532','mnb7
8932']
let expDateDate =
['12/30/2029','03/18/2021','09/01/2020','
01/01/2023','10/01/2021']

Pross Cons
However, as the data becomes more
and more complicated, not just more
data, the medication information will
become corrupted. It is too difficult
to keep everything straight;
everything lined up, let alone passing
this data to a function. Bugs will
creap into this code and the
application it is part of will fail.

Second approach

let medications = [
['Lactated
Ringers','levothyroxine','rosuvastatin','
albuterol','esomeprazole'],

['100L','2000ct','1500ct','1325ct','23145
ct'],

['13ab7','at342','gr5423','iuy6532','mnb7
8932'],
['12/30/2029','03/18/2021','09/01/2020','
01/01/2023','10/01/2021']
]

Pross Cons
This code is more organized, but has
the same index and complicatedness
problem as the first example, though
it is easier to pass the data in this
form to a function. However, when
writing code using this data, you
have to remember the order and
indices of all the sub-arrays. This will
be a constant problem as the data is
passed, bugs fixed, and the data
becomes more complicated.

Using defined objects


Defined objects allow us to mingle different types of data together, and build
relationships between the data. Using the medication example, you could put
a bunch of objects in an array. Each of these objects would hold one
medication's name, its manufacturer, its best-by date, the amount of the
medication on hand, and if that amount is a count or a volume in liters,
milliliters, etc.
The way you would accomplish this in JavaScript is to apply the concept of a
key-value pair. Being a BYU-Idaho student, you are familiar with key-value
pairs already. Your iNumber is a key, and the data you supplied to the school
about yourself is the value. Applying this concept to the medications data
representation problem, a possible, though not optimal, solution looks like
this, where id, amount, amountType, and expDate are the keys, and key-value
pairs are seperated by commas.
First approach

let lactatedRingers =
{'id':'13ab7','amount':100,'amountType':'
L','expDate':'12/30/2029'}
let levothyroxine =
{'id':'at342','amount':2000,'amountType':
'ct','expDate':'03/18/2021'}
let rosuvastatin =
{'id':'gr5423','amount':1500,'amountType'
:'ct','expDate':'09/01/2020'}
let albuterol =
{'id':'iuy6532','amount':1325,'amountType
':'ct','expDate':'01/01/2023'}
let esomeprazole =
{'id':'mnb78932','amount':23145,'amountTy
pe':'ct','expDate':'10/01/2021'}

Pross Cons
Though this solution improves on the
array representations, it suffers from
having to pass each of the
medications to functions that may
work with or on the data. Also, it is
easy to accidentally disconnect the
medication names from their
associated data. An additional layer
of keys and values is needed to
resolve this problem.
How to access the values associated with one of the keys?
A.- you use the name of the variable for the defined object and apply the key
to look up the value.

let anAmount = rosuvastatin['amount']


The variable anAmount would now contain 1500.
How to change the value in the objects?
A.- Changing a value works much like the code to modify a value in an array,
but you would apply a key instead of using an array index.

rosuvastatin['amount'] = 1455
Second approach

let medications = {
'Lactated Ringers' :
{'id':'13ab7','amount':100,'amountType':'
L','expDate':'12/30/2029'},
'Levothyroxine' :
{'id':'at342','amount':2000,'amountType':
'ct','expDate':'03/18/2021'},
'Rosuvastatin' :
{'id':'gr5423','amount':1500,'amountType'
:'ct','expDate':'09/01/2020'},
'Albuterol' :
{'id':'iuy6532','amount':1325,'amountType
':'ct','expDate':'01/01/2023'},
'Esomeprazole' :
{'id':'mnb78932','amount':23145,'amountTy
pe':'ct','expDate':'10/01/2021'}
}
Pross Cons
In this solution, a defined object for
all the medications contains other
defined objects. This is much like a
two dimentional array, an array that
contains other arrays. Here, the
name of the medication, with correct
capitalization, is used as a key, and
the data for that medication is the
key's associated value.
Another advantage of this
organization of the data is there is no
need to remember the order of the
data. If you wanted all the data for
Lactated Ringers, the code would
look like this.

How to access all the data for Lactated Ringers?


A.- By writing this code:

let aMedication = medications['Lactated


Ringers']
How to get the expiration data for albuterol without getting all the data?
A.-

let aBestByDate =
medications['Albuterol']['expDate']
How to change the amount of Rosuvastatin on hand?
A.- The code would look like this:

medications['Rosuvastatin']['amount'] =
1432
Another way using dot notation
When you have defined objects, there is another way to access and change
values. It uses what is called 'dot notation' by the JavaScript community. Let's
look at the example where the amount of Rosuvastatin was changed again.
You could do it like this.
medications.Rosuvastatin.amount = 1432
That's kind of nice. Many fewer characters to type. You drop all the brackets
and quotation marks. But can you use dot notation to set a value? Yep. You
can. Here is the Albutorol example from earlier rewritten using dot notation.
let aBestByDate = medications.Albuterol.expDate
What are the limitations of using dot notation?
A.-
It may seem that, because dot notation is so much less wordy, it should
always be used. Not so fast. There are times when it doesn't work. It only
works when you know what the keys are at the time you are writting your
code. Let me explain.
Suppose you had a user interface where the user selected the name of the
medication to display the expiration data for. Now you have a problem. You
have to put what the user selected into a variable in order to be able to use it.
Let's say you put it in a variable called 'selectedMedication'. The temptation is
to think that this code would work.
let aBestByDate = medications.selectedMedication.expDate
It doesn't. This code does work though.
let aBestByDate = medications[selectedMedication]['expDate']
This code works too. It combines both approaches and is probably the
cleanest code to solve this problem.
let aBestByDate = medications[selectedMedication].expDate
If nothing else, JavaScript is very flexible. So which one should you use? It
depends on which works to solve the problem you are working on. Pick the
one that is the simplest for any given situation.

4.5 JavaScript Array Functions

What is functional programming?


A.- It is a programing paradigm that treats computation as the evaluation of
mathematical functions and avoids changing-state and mutable data. It is a
declarative programing paradigm, which means programming is done with
expressions or declarations instead of statements.

What are the array methods that support functional programing and what
do they do?
A.- They are filter(), map(), and reduce() among others. For now, they will be
our focus.
Array method What it does?
array.filter() The array.filter() method creates a filtered array from the
original array using the condition from the provided
function.
array.map() The array.map() method iterates through each element of
the original array using a given function and produces a
new array. The original array is not modified. The new
array is returned by the map() method. The new array will
have the same number of elements as the original array.
array.reduce() The array.reduce() method is used to reduce the array to a
single value. It executes a reducer function on each
element of the array, resulting in a single output value.
The reducer function takes four arguments: Accumulator,
Current Value, Current Index, Source Array. The reducer
function's returned value is assigned to the accumulator,
whose value is remembered across each iteration
throughout the array and ultimately becomes the final,
single resulting value.

4.5.1 Array filter


https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
Global_Objects/Array/filter
What does this method do?
A.- The filter() method of Array instances creates a shallow copy of a portion
of a given array, filtered down to just the elements from the given array that
pass the test implemented by the provided function.
Syntax
filter(callbackFn)
filter(callbackFn, thisArg)

Parameters:
callbackFn

A function to execute for each element in the array. It should


return a truthy value to keep the element in the resulting array,
and a falsy value otherwise. The function is called with the
following arguments:

element

The current element being processed in the array.

index

The index of the current element being processed in the array.

array

The array filter() was called upon.

thisArg Optional
Description
The filter() method is an iterative method. It calls a
provided callbackFn function once for each element in an array, and
constructs a new array of all the values for which callbackFn returns
a truthy value. Array elements which do not pass the callbackFn test are not
included in the new array. Read the iterative methods section for more
information about how these methods work in general.
callbackFn is invoked only for array indexes which have assigned values. It is
not invoked for empty slots in sparse arrays.
The filter() method is generic. It only expects the this value to have
a length property and integer-keyed properties.
Open in Vs for examples here.
4.5.2 Array map
Syntax
map(callbackFn)
map(callbackFn, thisArg)

Parameters:
callbackFn

A function to execute for each element in the array. Its return


value is added as a single element in the new array. The function
is called with the following arguments:

element

The current element being processed in the array.

index

The index of the current element being processed in the array.

array

The array map() was called upon.

thisArg Optional
A value to use as this when executing callbackFn. See iterative
methods.

Return value
A new array with each element being the result of the callback function.
Description
The map() method is an iterative method. It calls a
provided callbackFn function once for each element in an array and
constructs a new array from the results. Read the iterative methods section
for more information about how these methods work in general.
callbackFn is invoked only for array indexes which have assigned values. It is
not invoked for empty slots in sparse arrays.
The map() method is generic. It only expects the this value to have
a length property and integer-keyed properties.
Since map builds a new array, calling it without using the returned array is an
anti-pattern; use forEach or for...of instead.
Para ver ejemplos ir a:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
Global_Objects/Array/map
4.5.3 Array reduce

The reduce() method of Array instances executes a user-supplied "reducer"


callback function on each element of the array, in order, passing in the return
value from the calculation on the preceding element. The final result of
running the reducer across all elements of the array is a single value.
The first time that the callback is run there is no "return value of the previous
calculation". If supplied, an initial value may be used in its place. Otherwise
the array element at index 0 is used as the initial value and iteration starts
from the next element (index 1 instead of index 0).
const array1 = [1, 2, 3, 4];

// 0 + 1 + 2 + 3 + 4
const initialValue = 0;
const sumWithInitial = array1.reduce(
(accumulator, currentValue) => accumulator + currentValue,
initialValue,
);

console.log(sumWithInitial);
// Expected output: 10

Syntax
reduce(callbackFn)
reduce(callbackFn, initialValue)

Parameters:
callbackFn

A function to execute for each element in the array. Its return


value becomes the value of the accumulator parameter on the next
invocation of callbackFn. For the last invocation, the return value
becomes the return value of reduce(). The function is called with the
following arguments:

accumulator

The value resulting from the previous call to callbackFn. On the first
call, its value is initialValue if the latter is specified; otherwise its
value is array[0].

currentValue

The value of the current element. On the first call, its value
is array[0] if initialValue is specified; otherwise its value is array[1].

currentIndex

The index position of currentValue in the array. On the first call, its
value is 0 if initialValue is specified, otherwise 1.
array

The array reduce() was called upon.

initialValue Optional

A value to which accumulator is initialized the first time the callback is called.
If initialValue is specified, callbackFn starts executing with the first value in
the array as currentValue. If initialValue is not specified, accumulator is
initialized to the first value in the array, and callbackFn starts executing with
the second value in the array as currentValue. In this case, if the array is
empty (so that there's no first value to return as accumulator), an error is
thrown.
Return value
The value that results from running the "reducer" callback function to
completion over the entire array.
What are some edge cases?
A.- If the array only has one element (regardless of position) and
no initialValue is provided, or if initialValue is provided but the array is
empty, the solo value will be returned without calling callbackFn.
If initialValue is provided and the array is not empty, then the reduce method
will always invoke the callback function starting at index 0.
If initialValue is not provided then the reduce method will act differently for
arrays with length larger than 1, equal to 1 and 0, as shown in the following
example:

const getMax = (a, b) => Math.max(a, b);

// callback is invoked for each element in the array starting at index 0


[1, 100].reduce(getMax, 50); // 100
[50].reduce(getMax, 10); // 50

// callback is invoked once for element at index 1


[1, 100].reduce(getMax); // 100

// callback is not invoked


[50].reduce(getMax); // 50
[].reduce(getMax, 1); // 1

[].reduce(getMax); // TypeError

How reduce() works without an initial value?


JS
const array = [15, 16, 17, 18, 19];

function reducer(accumulator, currentValue, index) {


const returns = accumulator + currentValue;
console.log(
`accumulator: ${accumulator}, currentValue: ${currentValue}, index: ${index},
returns: ${returns}`,
);
return returns;
}

array.reduce(reducer);

The callback would be invoked four times, with the arguments and return
values in each call being as follows:

currentValue index Return value


accumulator

First call 15 16 1 31

Second call 31 17 2 48

Third call 48 18 3 66

Fourth call 66 19 4 85

The array parameter never changes through the process — it's always [15, 16,
17, 18, 19]. The value returned by reduce() would be that of the last callback
invocation (85).
How reduce() works with an initial value?
A.- Here we reduce the same array using the same algorithm, but with
an initialValue of 10 passed as the second argument to reduce():
[15, 16, 17, 18, 19].reduce(
(accumulator, currentValue) => accumulator + currentValue,
10,
);

The callback would be invoked five times, with the arguments and return
values in each call being as follows:

currentValue index Return value


accumulator

First call 10 15 0 25

Second call 25 16 1 41

Third call 41 17 2 58

Fourth call 58 18 3 76
The value returned by reduce() in this case would be 95.

4.5.3.1 Examples
Sum of values in an object array
To sum up the values contained in an array of objects, you must supply
an initialValue, so that each item passes through your function.
JS
const objects = [{ x: 1 }, { x: 2 }, { x: 3 }];
const sum = objects.reduce(
(accumulator, currentValue) => accumulator + currentValue.x,
0,
);

console.log(sum); // 6
Function sequential piping
The pipe function takes a sequence of functions and returns a new function.
When the new function is called with an argument, the sequence of functions
are called in order, which each one receiving the return value of the previous
function.
JS
const pipe =
(...functions) =>
(initialValue) =>
functions.reduce((acc, fn) => fn(acc), initialValue);

// Building blocks to use for composition


const double = (x) => 2 * x;
const triple = (x) => 3 * x;
const quadruple = (x) => 4 * x;

// Composed functions for multiplication of specific values


const multiply6 = pipe(double, triple);
const multiply9 = pipe(triple, triple);
const multiply16 = pipe(quadruple, quadruple);
const multiply24 = pipe(double, triple, quadruple);

// Usage
multiply6(6); // 36
multiply9(9); // 81
multiply16(16); // 256
multiply24(10); // 240

Running promises in sequence


Promise sequencing is essentially function piping demonstrated in the
previous section, except done asynchronously.

// Compare this with pipe: fn(acc) is changed to acc.then(fn),


// and initialValue is ensured to be a promise
const asyncPipe =
(...functions) =>
(initialValue) =>
functions.reduce((acc, fn) => acc.then(fn), Promise.resolve(initialValue));
// Building blocks to use for composition
const p1 = async (a) => a * 5;
const p2 = async (a) => a * 2;
// The composed functions can also return non-promises, because the values are
// all eventually wrapped in promises
const f3 = (a) => a * 3;
const p4 = async (a) => a * 4;

asyncPipe(p1, p2, f3, p4)(10).then(console.log); // 1200

Using reduce() with sparse arrays

reduce() skips missing elements in sparse arrays, but it does not


skip undefined values.

JSCopy to Clipboard
console.log([1, 2, , 4].reduce((a, b) => a + b)); // 7
console.log([1, 2, undefined, 4].reduce((a, b) => a + b)); // NaN

Calling reduce() on non-array objects


The reduce() method reads the length property of this and then accesses
each property whose key is a nonnegative integer less than length.
JSCopy to Clipboard
const arrayLike = {
length: 3,
0: 2,
1: 3,
2: 4,
3: 99, // ignored by reduce() since length is 3
};
console.log(Array.prototype.reduce.call(arrayLike, (x, y) => x + y));
// 9
When not to use reduce?

Multipurpose higher-order functions like reduce() can be powerful but


sometimes difficult to understand, especially for less-experienced
JavaScript developers. If code becomes clearer when using other array
methods, developers must weigh the readability tradeoff against the
other benefits of using reduce().

Note that reduce() is always equivalent to a for...of loop, except that


instead of mutating a variable in the upper scope, we now return the
new value for each iteration:

JSCopy to Clipboard
const val = array.reduce((acc, cur) => update(acc, cur), initialValue);

// Is equivalent to:
let val = initialValue;
for (const cur of array) {
val = update(val, cur);
}

As previously stated, the reason why people may want to use reduce() is
to mimic functional programming practices of immutable data.
Therefore, developers who uphold the immutability of the accumulator
often copy the entire accumulator for each iteration, like this:

JSCopy to Clipboard
const names = ["Alice", "Bob", "Tiff", "Bruce", "Alice"];
const countedNames = names.reduce((allNames, name) => {
const currCount = Object.hasOwn(allNames, name) ? allNames[name] : 0;
return {
...allNames,
[name]: currCount + 1,
};
}, {});

This code is ill-performing, because each iteration has to copy the


entire allNames object, which could be big, depending how many unique
names there are. This code has worst-case O(N^2) performance,
where N is the length of names.

A better alternative is to mutate the allNames object on each iteration.


However, if allNames gets mutated anyway, you may want to convert
the reduce() to a simple for loop instead, which is much clearer:

JSCopy to Clipboard
const names = ["Alice", "Bob", "Tiff", "Bruce", "Alice"];
const countedNames = names.reduce((allNames, name) => {
const currCount = allNames[name] ?? 0;
allNames[name] = currCount + 1;
// return allNames, otherwise the next iteration receives undefined
return allNames;
}, Object.create(null));
JSCopy to Clipboard
const names = ["Alice", "Bob", "Tiff", "Bruce", "Alice"];
const countedNames = Object.create(null);
for (const name of names) {
const currCount = countedNames[name] ?? 0;
countedNames[name] = currCount + 1;
}

Therefore, if your accumulator is an array or an object and you are


copying the array or object on each iteration, you may accidentally
introduce quadratic complexity into your code, causing performance to
quickly degrade on large data. This has happened in real-world code —
see for example Making Tanstack Table 1000x faster with a 1 line
change.

Some of the acceptable use cases of reduce() are given above (most
notably, summing an array, promise sequencing, and function piping).
There are other cases where better alternatives than reduce() exist.

 Flattening an array of arrays. Use flat() instead.

JSCopy to Clipboard
const flattened = array.reduce((acc, cur) => acc.concat(cur), []);

JSCopy to Clipboard
const flattened = array.flat();

 Grouping objects by a property. Use Object.groupBy() instead.

JSCopy to Clipboard
const groups = array.reduce((acc, obj) => {
const key = obj.name;
const curGroup = acc[key] ?? [];
return { ...acc, [key]: [...curGroup, obj] };
}, {});

JSCopy to Clipboard
const groups = Object.groupBy(array, (obj) => obj.name);

 Concatenating arrays contained in an array of objects.


Use flatMap() instead.

JSCopy to Clipboard
const friends = [
{ name: "Anna", books: ["Bible", "Harry Potter"] },
{ name: "Bob", books: ["War and peace", "Romeo and Juliet"] },
{ name: "Alice", books: ["The Lord of the Rings", "The Shining"] },
];
const allBooks = friends.reduce((acc, cur) => [...acc, ...cur.books], []);

JSCopy to Clipboard
const allBooks = friends.flatMap((person) => person.books);

 Removing duplicate items in an array.


Use Set and Array.from() instead.

JSCopy to Clipboard
const uniqArray = array.reduce(
(acc, cur) => (acc.includes(cur) ? acc : [...acc, cur]),
[],
);

JSCopy to Clipboard
const uniqArray = Array.from(new Set(array));

 Eliminating or adding elements in an array.


Use flatMap() instead.

JSCopy to Clipboard
// Takes an array of numbers and splits perfect squares into its square roots
const roots = array.reduce((acc, cur) => {
if (cur < 0) return acc;
const root = Math.sqrt(cur);
if (Number.isInteger(root)) return [...acc, root, root];
return [...acc, cur];
}, []);

JSCopy to Clipboard
const roots = array.flatMap((val) => {
if (val < 0) return [];
const root = Math.sqrt(val);
if (Number.isInteger(root)) return [root, root];
return [val];
});

If you are only eliminating elements from an array, you


also can use filter().

 Searching for elements or testing if elements satisfy a


condition. Use find() and findIndex(),
or some() and every() instead. These methods have the
additional benefit that they return as soon as the result is
certain, without iterating the entire array.

JSCopy to Clipboard
const allEven = array.reduce((acc, cur) => acc && cur % 2 === 0, true);

JSCopy to Clipboard
const allEven = array.every((val) => val % 2 === 0);

In cases where reduce() is the best choice, documentation and semantic


variable naming can help mitigate readability drawbacks.

What are the best situations for using array reduce method?

What are alternatives to this method that performs better?


What are the limitations of this method?

4.6 Assignment
The JS code below allows to filter temples according to the dedication date
and the total area. When a user click on the navigation bar options the
temples that meet the requirements are shown:
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-
scale=1.0">
<title>WDD 131 - Dynamic Web Fundamentals - Carlos Medina</title>
<meta name="description" content="WDD 131 - Dynamic Web
Fundamentals|Carlos Manuel Medina Sullca|Temples page"/>
<meta name="author" content="Carlos Medina"/>
<link href="styles/filtered-temples.css" rel="stylesheet"/>
<link href="styles/filtered-temples-large.css" rel="stylesheet"/>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com"
crossorigin>
<link href="https://fonts.googleapis.com/css2?
family=Roboto:wght@300;400;700&display=swap" rel="stylesheet">
<script src="scripts/filtered-temples.js" defer></script>
</head>
<body>
<header>
<h1>Temple Album</h1>
<button id="hamMenu"></button>
<nav class="navigation">
<a href="#" title="Home" id="returnHome">Home</a>
<a href="#" title="Old" id="oldTemples">Old</a>
<a href="#" title="New" id="newTemples">New</a>
<a href="#" title="Large" id="largeTemples">Large</a>
<a href="#" title="Small" id="smallTemples">Small</a>
</nav>
</header>
<main>
<h2>Home</h2>
<div class="filtTemples">
</div>
</main>
<footer>
<p>&copy;<span id="currentyear"></span> | Carlos Medina |
Bolivia</p>
<p>Last Modification: <span id="lastModified"></span></p>
</footer>
</body>
</html>

CSS small screen


* {
font-family: "Roboto", sans-serif;
margin: 0 auto;
padding: 0;
}
h1 {
color: white;
}

h2 {
font-weight: 400;
color: black;
font-size: 1.5rem;
margin: 1rem auto;
}
header {
background-color: #e24b05;
padding: 10px;
border: 1px solid rgba(0, 0, 0, 0.1);
box-shadow: 0 0 10px #e24b05;
}
main {
margin: 1rem auto;
display: grid;
grid-gap: 1rem;
padding-top: 2.5rem;
padding-bottom: 2.5rem ;
}
section {
display: grid;
background-color:#8aacbc;
padding: 1.5rem;
box-shadow: -0.1em 0 0.8em gray;
}

section p{
padding:0.1em;
font-size: small;
}

.filtTemples {
display: grid;
grid-gap: 2rem;
}

#hamMenu {
font-size: 1.5rem;
border: 0;
background: none;
color: white;
position: absolute;
top: 1rem;
right: 1rem;
}

#hamMenu::before {
content: "≡";

#hamMenu.open::before {
content: "⬅️";
}

.navigation {
display: flex;
flex-direction: column;
list-style: none;
background-color: #e24b05;
color: #fff;
}

.navigation a {
display: none;
padding: 0.5rem;
text-align: center;
text-decoration: none;
color: #fff;
}
.navigation a:hover {
background-color: #8bd1f1;
color: #333;
font-weight: 700;
}

/* when the button is clicked - the open class is toggled


(added/removed) */
.open a {
display: block;
}

footer {
text-align: center;
background-color: #e24b05;
height: 4rem;
align-content: center;
color: white;
}

footer p {
padding: 0.2rem;
}

p {
padding: 1.5rem;
}

CSS large screen


@media (min-width: 37.5em) {
#hamMenu {
display: none;
}
header {
display: flex;
align-items: center;
justify-content: space-between;
}

.navigation {
flex-direction: row;
background-color: transparent;
}
.navigation a {
display: block;
flex: 1 1 100%;
color: white;
padding: 1.5rem;
text-decoration: none;
}
.navigation a:hover {
text-decoration:wavy;
}
section p{
font-size: large;
}
.filtTemples {
max-width: 70%;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 2rem;
}

img {
max-width: 100%;
height: auto;
}
}

JS
const hamButton = document.querySelector('#hamMenu');
const navigation = document.querySelector('.navigation');

hamButton.addEventListener('click', () => {
navigation.classList.toggle('open');
hamButton.classList.toggle('open');
});
/*
const curYear = document.querySelector("#currentYear");
const lmod = document.querySelector("#lastModified");
const today = new Date();
curYear.innerHTML = `${today.getFullYear()}`;
lmod.innerHTML = `Last Modification: ${new Date(document.lastModified)}`;*/
const curYear = document.querySelector("#currentYear");
const lmod = document.querySelector("#lastModified");
const today = new Date();
currentyear.innerHTML = `<span>${today.getFullYear()}</span>`;
let oLastModif = new Date(document.lastModified);
lastModified.innerHTML= `<span>${oLastModif}</span>`;

const temples = [
{
templeName: "Aba Nigeria",
location: "Aba, Nigeria",
dedicated: "2005, August, 7",
area: 11500,
imageUrl:
"https://content.churchofjesuschrist.org/templesldsorg/bc/Temples/photo-
galleries/aba-nigeria/400x250/aba-nigeria-temple-lds-273999-wallpaper.jpg"
},
{
templeName: "Manti Utah",
location: "Manti, Utah, United States",
dedicated: "1888, May, 21",
area: 74792,
imageUrl:
"https://content.churchofjesuschrist.org/templesldsorg/bc/Temples/photo-
galleries/manti-utah/400x250/manti-temple-768192-wallpaper.jpg"
},
{
templeName: "Payson Utah",
location: "Payson, Utah, United States",
dedicated: "2015, June, 7",
area: 96630,
imageUrl:
"https://content.churchofjesuschrist.org/templesldsorg/bc/Temples/photo-
galleries/payson-utah/400x225/payson-utah-temple-exterior-1416671-wallpaper.jpg"
},
{
templeName: "Yigo Guam",
location: "Yigo, Guam",
dedicated: "2020, May, 2",
area: 6861,
imageUrl:
"https://content.churchofjesuschrist.org/templesldsorg/bc/Temples/photo-
galleries/yigo-guam/400x250/yigo_guam_temple_2.jpg"
},
{
templeName: "Washington D.C.",
location: "Kensington, Maryland, United States",
dedicated: "1974, November, 19",
area: 156558,
imageUrl:
"https://content.churchofjesuschrist.org/templesldsorg/bc/Temples/photo-
galleries/washington-dc/400x250/washington_dc_temple-exterior-2.jpeg"
},
{
templeName: "Lima Perú",
location: "Lima, Perú",
dedicated: "1986, January, 10",
area: 9600,
imageUrl:
"https://content.churchofjesuschrist.org/templesldsorg/bc/Temples/photo-
galleries/lima-peru/400x250/lima-peru-temple-evening-1075606-wallpaper.jpg"
},
{
templeName: "Mexico City Mexico",
location: "Mexico City, Mexico",
dedicated: "1983, December, 2",
area: 116642,
imageUrl:
"https://content.churchofjesuschrist.org/templesldsorg/bc/Temples/photo-
galleries/mexico-city-mexico/400x250/mexico-city-temple-exterior-1518361-wallpaper.jpg"
},
// Add more temples from here
{
templeName: "Anchorage Alaska",
location: "Anchorage, Alaska, United States",
dedicated: "1999, January, 9",
area: 116642,
imageUrl:
"https://content.churchofjesuschrist.org/templesldsorg/bc/Temples/photo-
galleries/anchorage-alaska/400x250/anchorage-temple-lds-746769-wallpaper.jpg"
},
{
templeName: "Arequipa Perú",
location: "Arequipa, Perú",
dedicated: "2019, December, 15",
area: 26969,
imageUrl:
"https://content.churchofjesuschrist.org/templesldsorg/bc/Temples/photo-
galleries/arequipa-peru/400x250/1-55f6c59ce8f9c093a9c689067f8674335de544e2.jpeg"
},
{
templeName: "Los Angeles California",
location: "Los Angeles, California, United States",
dedicated: "1956, March, 1956",
area: 190614,
imageUrl:
"https://content.churchofjesuschrist.org/templesldsorg/bc/Temples/photo-
galleries/los-angeles-california/400x250/los-angeles-california-temple-1079458-
wallpaper.jpg"
},
{
templeName: "Cochabamba Bolivia",
location: "Cochabamba, Bolivia",
dedicated: "2000, Abril, 30",
area: 33302,
imageUrl:

"https://www.churchofjesuschrist.org/imgs/e012ebb4075dc7976a314471fc0a3b3058e37c1a/
full/320%2C/0/default"
},
// Add more temple objects here...
];

createTempleCard(temples);

const oldLink= document.querySelector("#oldTemples");


const newLink= document.querySelector("#newTemples");
const largeLink= document.querySelector("#largeTemples");
const smallLink= document.querySelector("#smallTemples");
const homeLink= document.querySelector("#returnHome");

largeLink.addEventListener("click", () => {
createTempleCard(temples.filter(temple => temple.area>90000
));
});

smallLink.addEventListener("click", () => {
createTempleCard(temples.filter(temple => temple.area<100000
));
});

oldLink.addEventListener("click", () => {
createTempleCard(temples.filter(temple => parseInt(temple.dedicated)<1900
));
});

newLink.addEventListener("click", () => {
createTempleCard(temples.filter(temple => parseInt(temple.dedicated)>2000
));
});

homeLink.addEventListener("click", () => {
createTempleCard(temples)
});

function createTempleCard(filteredTemples) {
document.querySelector(".filtTemples").innerHTML = "";
filteredTemples.forEach(temple => {
let card = document.createElement("section");
let name = document.createElement("h3");
let location = document.createElement("p");
let dedication = document.createElement("p");
let area = document.createElement("p");
let img = document.createElement("img");

name.textContent = temple.templeName;
location.innerHTML = `<span class="label">Location:</span> ${temple.location}`;
dedication.innerHTML = `<span class="label">Dedicated:</span> $
{temple.dedicated}`;
area.innerHTML = `<span class="label">Size:</span> ${temple.area} sq ft`;
img.setAttribute("src", temple.imageUrl);
img.setAttribute("alt", `${temple.templeName} Temple`);
img.setAttribute("loading", "lazy");

card.appendChild(name);
card.appendChild(location);
card.appendChild(dedication);
card.appendChild(area);
card.appendChild(img);

document.querySelector(".filtTemples").appendChild(card);
});
}
Chapter 5 Forms, JavaScript Callback Functions and local
storage
5.1 HTML forms
5.1.1 General accessibility guidance for forms
https://designsystem.digital.gov/components/form/
Accessibility guidance
 Don’t control element order with CSS. Display form controls in the
same order in the HTML as they appear on screen. Don’t use CSS to
rearrange the form controls. Screen readers narrate form elements in
the order they appear in the HTML.
 Align validation with inputs. Visually align validation messages with
the input fields so people using screen magnifiers can read them
quickly.
 Use proper markup. Group each set of thematically related controls in
a fieldset element. Use the legend element to offer a label within each
one. The fieldset and legend elements make it easier for those who use
screen readers to navigate the form.
 Use legends. Use a single legend for fieldset (this is required). One
common use of the fieldset and legend elements is a question with
radio-button options for answers. The question text and radio buttons
are wrapped in a fieldset, with the question itself being inside the
legend tag.

 Embed multiple fieldsets and legends for more complex forms.


 Use simple vertical layouts. Keep your form blocks in a vertical pattern.
This approach is ideal, from an accessibility standpoint, because of
limited vision that makes it hard to scan from right to left.

Identifying required fields


 Show whether a field is required or optional. Mark required fields as
required by using a red asterisk (*).
 Use text descriptions. Combine red asterisks (*) with a text description
at the top of the form instructing the user of its meaning.
Example: “A red asterisk (*) indicates a required field.”
 Use the required attribute. Add the required attribute to your form
elements to indicate that a field must be filled out before submitting
the form.
 Mark optional fields as "optional." Label optional fields with the word
“optional” placed in parentheses.
Example: (optional)
 Let users know if there is an error. Use a message or alert to notify the
user if a field that is required was not completed, and indicate which
field was not completed. Additionally, include an error notification in
the page title (title element) for screen readers.
 Note: One-field forms are the exception and do not need to be marked
with a required label or symbol.

Known issues with screen readers


 VoiceOver on iOS currently does not support fieldset and legend
elements for forms. You can address this issue by using aria-
labelledby="for-attribute-of-label id-of-legend id-of-additional-info" on
each input in the fieldset. Using aria-labelledby will overwrite the
default text read by the screen reader, so it is important to include all
relevant information.
 VoiceOver on OS X offers partial support for aria-describedby. There's
full support for conveying description on text inputs, partial support for
description changes when the text input is in focus, and no support
for role="alert". Visit a11ysupport.io to view the full status of support.
Note: These components have been designed to support a wide range of
screen readers, but they may not work with all versions.

Form settings:
Variable Description
$theme-form-font-family Font family of the form.

5.1.2 Learning about html5 form attributes


https://www.sitepoint.com/html5-form-attributes-part-2/?
utm_content=bufferd6894&utm_medium=social&utm_source=facebook.com
&utm_campaign=buffer
To see an example of form input pattern testing go to the link:
https://codepen.io/Carlos-Manuel-Medina-Sullca/pen/OJeyNmL
5.1.3 Webforms
Best practices for web forms
Labelling:
Title first describing the purpose of the form.
Submit button, never use the word submit, complete the phrase “I want to..
(name of the submit button)”·
Ask only for necessary info., name and email address.
Content:
Let users know the required fields.
Layout:
Never use columns for a form.
Keep the fields in straight line.
Keep a single field for phone number.
Inputs:
Add placeholders in fields that describe the info. required.
Submission:
Never add a reset button. If it is necessary the refresh option should be used.
Design:
Beautiful design inspires confidence.
5.1.3.1 CSS attributes selectors to style forms
To style input types the next selector must be used:
Input[type= “text”] {color: deeppink;}
Beautiful content about forms can be used in the folder Form videos inside
folder W5. Click here to go
5.1.3.2 An example of web forms

HTML
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="description" content="Fill Me In">
<meta name="author" content="John Doe">

<!-- This start file was build by Paul Cheney -->


<title>HTML5 Start Site by Paul Cheney</title>

<!-- TELLS PHONES NOT TO LIE ABOUT THEIR WIDTH & stops the font from
enlarging when a phone is turned sideways-->
<meta name="viewport" content="width=device-width, initial-scale=1,
maximum-scale=1">

<!-- STYLE SHEETS -->


<link href="css/normalize.css" rel="stylesheet">
<!-- phone-default -->
<link href="css/small.css" rel="stylesheet">
<!-- enhance-tablet -->
<link href="css/medium.css" rel="stylesheet">
<!-- enhance-desktop -->
<link href="css/large.css" rel="stylesheet">

</head>
<body>
<!-- HEADER HERE -->
<header>
<h1>Course Proposal</h1>
<h2>Designing Web Forms</h2>
</header>

<!-- NAVIGATION HERE -->


<nav>
<ul>
<li><a href="#">About</a></li>
<li class="active"><a href="#">Propose</a></li>
<li><a href="#">Winners</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>

<!-- CONTENT HERE -->


<main>
<h1>Course Proposal Application</h1>
<form method="get" action="thanks.html" class="wf1">
<fieldset>
<legend>Applicant Information</legend>
<label>First name*<input type="text" name="fname"
required></label>
<label>Last name*<input type="text" name="lname"
required></label>
<label>Phone<input type="tel" name="phone"
placeholder="12345678"></label>
<label>Email*<input type="email" name="email"
placeholder="someone@gmail.com" required></label>
<label>Website<input type="url" name="url"
placeholder="http://"></label>
</fieldset>

<fieldset>
<legend>Course information</legend>
<div>Audience</div>
<label><input type="radio" name="audience"
value="beginner">Beginner</label>
<label><input type="radio" name="audience"
value="beginner">Intermediate</label>
<label><input type="radio" name="audience"
value="beginner">Advance</label>

<div>Software Needed</div>
<label><input type="checkbox" name="editing"
value="yes">Photo editting</label>
<label><input type="checkbox" name="code"
value="yes">Coding</label>
<label><input type="checkbox" name="process"
value="yes">Preprocess</label>
<label><input type="checkbox" name="client"
value="yes">FTP Client</label>
</fieldset>

<fieldset>
<legend>Funding</legend>
<label>Anticipated Completion Date<input type="date"
name="completeDate"></label>
<label>Course Subject
<select name="subject">
<option value="">Please select &#9662;</option>
<option value="software">Software
Development</option>
<option value="creative">Creative
Professional</option>
<option value="info">Information
technology</option>
<option value="data">Data Professional</option>
<option
value="construction">Construction</option>
<option
value="manufacturing">Manufacturing</option>
<option value="business">Business
Professional</option>
<option value="security">Cyber Security</option>
</select>
</label>
<label>How many authors <input type="number"
name="authors"></label>
<label>
</fieldset>
<input type="submit" value="Propose my course">

</form>

</main>

<!-- FOOTER HERE -->


<footer>
&copy; 2024 &bull; Paul Cheney &bull; 123-555-6789
</footer>
<script src="js/scripts.js"></script>
</body>
</html>

CSS
/* Prevent adjustments of font size after orientation changes in IE
on Windows Phone and in iOS. */
html {-webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%;}

/*----------- apply a natural box layout model to all elements


--------------*/
* { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-
sizing: border-box; }

/*----------- BODY --------------*/


body {
font-size: 16px;
font-family: Verdana, sans-serif;
}

/*----------- HEADER --------------*/


header {
padding: .5rem 2%;
background-color: #ddd;
}
header h1 {margin: 0;}
header h2 {margin: 0; font-weight: normal;}
/*----------- NAVIGATION --------------*/
nav {
background-color: #666;
}
nav ul {
list-style-type: none;
padding: 0;
margin: 0;
}
nav ul li {border-bottom: solid 1px #333;}
nav ul li a {
display: block;
background-color: #444;
color: #eee;
padding: .5rem 0;
text-decoration: none;
font-size: .9rem;
text-align: center;
}
nav ul li.active a {
background-color: #000;
color: #fff;
}
/*----------- MAIN --------------*/
main {
padding: 0 2%;
min-height: 20rem;
}

/*-------------FORM STYLING--------------*/
.wf1 fieldset {
margin: 2rem 0;
border: 1px solid #ddd;
border-radius: 6px;
padding: .5rem 2%;
}

.wf1 legend {
color: #445ba9;
padding: 0 .5rem;
}

.wf1 label {
display: block;
padding-top: 1rem;
color: #9c2c13;

.wf1 div {
padding-top: 1rem;
color: #445ba9;
font-size: 0.9rem;
}

.wf1 input[type="text"],
.wf1 input[type="tel"],
.wf1 input[type="email"],
.wf1 input[type="url"],
.wf1 input[type="date"],
.wf1 select,
.wf1 input[type="number"] {
background-color: #eee;
display: block;
border: solid 1px #999;
border-radius: 6px;
padding: 0.75rem;
color: #555;
width: 100%;
max-width: 400px;
appearance: none;
}

.wf1 input[type="radio"],
.wf1 input[type="checkbox"] {
margin-right: 6px;
}

.wf1 input[type="submit"] {
border: none;
background-image: linear-gradient(#9c2c13, #6f200e);
color: #fff;
border-radius: 6px;
padding: .8rem;
width: 96%;
max-width: 400px;
margin: -1rem 2% 2rem 2%;
box-shadow: 1px 1px 4px #999;
}
.wf1 input:required {
border-left: solid 8px red;
}

.wf1 input:required:valid {
border-left: solid 8px green;
}

/*----------- FOOTER --------------*/


footer {
background-color: #ddd;
padding: .5rem 2%;
text-align: center;
}

Result
5.2 Callback functions

What are callback functions used for?


A.- At least for three things:
- Handling events.
- Processing data.
- Controlling the flow of a program
What is a callback function?
A.- It is a function passed into another function as an argument, which is then
invoked inside the outer function to complete some kind of routine or action.
5.2.1 Callback functions
What are the two in which a callback function may be called?
A.- Synchronous and asynchronous.
Synchronous callback Asynchronous callback
 They are called immediately  They are called at some point
after the invocation of the later after an asynchronous
outer function operation has completed.
 No intervene with
asynchronous tasks.

An example of synchronous and asynchronous


JS
let value = 1;

doSomething(() => {
value = 2;
});

console.log(value);

If doSomething calls the callback synchronously, then the last statement


would log 2 because value = 2 is synchronously executed; otherwise, if the
callback is asynchronous, the last statement would log 1 because value = 2 is
only executed after the console.log statement.
What are some synchronous and asynchronous callbacks?
A.-
Synchronous callback Asynchronous callback
the callbacks passed include the callbacks passed
to Array.prototype.map(), Array.prototy to setTimeout() and Promise.protot
pe.forEach() ype.then().

5.2.2 Array callback methods & arrow


functions
https://blog.devgenius.io/array-callback-methods-arrow-functions-
9ecbd728f63
5.2.3 Activity instructions
Given these function declarations:
function calculate(a, b, callback) {
callback(a + b);
}

function displayResult(result) {
console.log('The result is: ' + result);
}

Call a function named calculate and pass it the arguments to support the
console output of the following equation: 2 + 3. You need to
pass three arguments to the calculate function.
calculate(2, 3, displayResult)
A common example of a callback function is in JavaScript, particularly in
asynchronous operations such as handling events or making async requests.
Here is a simulated example:
function fetchData(callback) {
// using setTimeout to simulate fetching data from a server
setTimeout(() => {
// This calls the 'callback' function and passes data to
it.
callback('Data has been fetched');
}, 2000); // This simulates a 2-second delay from a
service.
}

// function that processes the data


function processData(data) {
console.log("Data received:", data);
}

// Call the fetchData function and pass the processData


function as an argument.
fetchData(processData);

The fetchData function simulates fetching data from a server by using the
setTimeout function to create a 2-second delay. After the delay, it calls the
provided callback function, passing the string 'Data has been fetched' as an
argument. In this context, the processData function is passed as the callback
to fetchData, and it logs the received data to the console when called.
5.3 Web storage API-local storage
What are the Web storage API mechanisms, and what do they provide?
A.-
They are APIS that provide the ability to store information in a key-value
format (e.g. key/value pairs) based upon a particular user agent or origin.

What are the two mechanisms within web storage?


A.- The two mechanisms within Web Storage are as follows:
 sessionStorage maintains a separate storage area for each
given origin that's available for the duration of the page session (as
long as the browser tab is open, including page reloads and restores).
 localStorage does the same thing, but persists even when the browser
is closed and reopened.

What are the properties through which these mechanisms are available?
A.-
These mechanisms are available via the Window.sessionStorage and
Window.localStorage properties. Invoking one of these will return an instance
of a Storage object, through which data items can be set, retrieved and
removed.
What does mean that both sessionStorage and localStorage are
synchronous?
A.- This means that when data is set, retrieved, or removed from these
storage mechanisms, the operations are performed synchronously, blocking
the execution of other JavaScript code until the operation is completed. This
synchronous behavior can potentially affect the performance of the web
application, especially if there is a large amount of data being stored or
retrieved
Developers should be cautious when performing operations
on sessionStorage or localStorage that involve a significant amount of data or
computationally intensive tasks. It is important to optimize code and
minimize synchronous operations to prevent blocking the user interface and
causing delays in the application's responsiveness.
What does the storage interface of the web storage API provide and allow?
A.- It provides access to a particular domain´s session or local storage. It
allows, for example, the addition, modification, or deletion of stored data
items.
What are the objects to call to manipulate the session storage for a domain
and for local storage?
A.- To manipulate, for instance, the session storage for a domain, a call
to Window.sessionStorage is made; whereas for local storage the call is made
to Window.localStorage.
What are the instance methods?
A.- Storage.key()
When passed a number n, this method will return the name of the nth key in
the storage.
Storage.getItem()
When passed a key name, will return that key's value.
Storage.setItem()
When passed a key name and value, will add that key to the storage, or
update that key's value if it already exists.
Storage.removeItem()
When passed a key name, will remove that key from the storage.
Storage.clear()
When invoked, will empty all keys out of the storage.

What is the purpose and scope of the localStorage mechanism available


through the Storage interface?
A.-

References:
https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API
https://developer.mozilla.org/en-US/docs/Web/API/
Storage#instance_properties
Comparison data between cookies, localStorage, and sessionStorage:
Local Storage Methods Comparison Chart

Cookies localStorage sessionStorage

Capacity ~4KB ~5MB ~5MB

Expires Manually set Never On tab/windows close

Accessible from Any window Any Window Same tab

What are the advantages of localStorage?


A.-
 This method is much more intuitive than using the older method of
Cookies.
 Only stores strings in key-value pairs.
 The mechanism's data persists without expiring and is available even
when an agent is closed and reopened again.
What is the approach to store non-string data in localStorage?
A.- One common approach is to use the JSON.stringify() method to convert
the data to a string before storing it, and then use the JSON.parse() method
to convert it back to its original form when you retrieve (recuperar) it from
localStorage. This allows you to store and retrieve more complex data
structures, such as objects and arrays, in localStorage.
What are some of the differences between session and local storage?
A.- One main difference is that localStorage data is persistent (remains) even
when the browser session expires. Session variables do not.
Using the Storage interface, what are some methods built into this interface
object and what do they do?
A.- Out of the entire method list [key(), getItem(), setItem(), removeItem(),
clear()] the most common are getItem() and setItem() which you will be using
in the assignments.
Example:
HTML CSS JS
<main> *{ 1// 1 Initialize display element variable
1️⃣
<h1>⚙️Using box- const visitsDisplay =
localStorage</h1> sizing: border- document.querySelector(".visits");
<p>This box;
demonstration page } // Get the stored VALUE for the
2️⃣
keeps track of the numVisits-ls KEY in localStorage if it
total number of body { exists. If the numVisits KEY is missing,
visits by a user height: then assign 0 to the numVisits
agent (client) on a 100vh; variable.
single page utilizing display: let numVisits =
the localStorage flex; Number(window.localStorage.getItem
option of the Web place- ("numVisits-ls")) || 0;
Storage API.</p> items: center;
justify- 3️⃣
// Determine if this is the first visit or
<p>Remember that content: display the number of visits. We wrote
localStorage stores center; this example backwards in order for
string values in key- font- you to think deeply about the logic.
value pairs.</p> family: if (numVisits !== 0) {
Roboto, sans- visitsDisplay.textContent =
<p><span serif; numVisits;
class="label">Numb margin: } else {
er of Visits: 0; visitsDisplay.textContent = `This
</span><span is your first visit. 🥳 Welcome!`;
class="visits"></spa padding: 0; }
n></p> }
</main> 4️⃣increment the number of visits by
//
main { one.
border: numVisits++;
1px solid
rgba(0, 0, 0, 5️⃣store the new visit total into
//
0.1); localStorage, key=numVisits-ls

padding: localStorage.setItem("numVisits-ls",
1rem; numVisits);
width:
760px; // 💡A client can view the localStorage
data using the Applications panel in
background- the browsers's DevTools - check it out
color: on any major site.
rgba(225,
225, 255, 0.2);
}

p{
margin:
1rem;
}

.label {
font-
family: Arial,
sans-serif;
font-
weight: 700;
}

#visits {
color:
navy;
font-
weight:
bolder;
font-
size: larger;
}

Result:

5.3.1 Activity overview

This activity revisits the favorite Book of Mormon chapters exercise. The
chapters entered by the user do not persist between visits to the application.
In other words, they are not stored anywhere. In this activity, we will use
localStorage to store the BOM chapter list for the user.
The high level directions for this problem would be "Enhance the favorite
Book of Mormon chapters application so that the users entries persist
between visits to the application using the localStorage API". Take on the
challenge by first thinking about a solution to this problem and map it out on
paper.
The directed plan is to create an array of valid book and chapter entries made
by the user. Then that array could be stored in localStorage as one large string
using JSON string using JSON.stringify(). This means we need to load that
array upon application load with the parsed data from localStorage, IF the
named localStorage component exists. Once loaded, we need to populate the
list with the stored values.
So instead of having two functions that do the same thing for the most part,
we will create a single function that appends the favorite chapter list with the
corresponding delete button, once on load, and also when a new entry is
made.

Activity Instructions
Note that the given example code is just an example. You may
have used different variable names, etc. You should never just
copy code.

1. Make a copy of your BOM application, by copying the


HTML, CSS, and JavaScript from the previous learning
activity into a week05 folder.
2. Open the JavaScript file. Declare
an array named chaptersArray and assign it to the results
of a defined function named getChapterList (This function
does not exist, yet).
3. In that same array variable declaration and assignment,
add a compound OR condition to assign it an empty
array in case this is the user's first visit or if the
localStorage item is missing.

This works because the function might not return


anything, so it is falsy which means it will revert to
assigning the empty array to chaptersArray.

Example
const input = document.querySelector('#favchap');
const button = document.querySelector('button');
const list = document.querySelector('#list');

let chaptersArray = getChapterList() || [];


Code Explanations

The first three lines establish references to the DOM elements that we
will be using in the program. Note that they only reference the HTML
element objects, not any properties.

The array declaration initializes the chaptersArray variable with the list
of chapters returned by the getChapterList() function or an empty array
if the function call returns null or undefined.

4. Now let's populate the displayed list of chapters. Use


a forEach on the chaptersArray to process each entry
named chapter. Use an arrow function within the loop to
call a new defined function named displayList and pass
it the argument of chapter. That way each entry will be
processed, i.e., appended to the list.
Example
chaptersArray.forEach(chapter => {
displayList(chapter);
});

5. Change the button click event listener to only do the following


tasks (the other tasks in that original function will be used in a
separate function named displayList):

 check if the input is empty, if not, then


 call displayList with the input.value argument,
 push the input.value into the chaptersArray,
 update the localStorage with the new array by calling a function
named setChapterList,
 set the input.value to nothing, and
 set the focus back to the input.
Example
button.addEventListener('click', () => {
if (input.value != '') { // make sure the input is not
empty
displayList(input.value); // call the function that
outputs the submitted chapter
chaptersArray.push(input.value); // add the chapter to
the array
setChapterList(); // update the localStorage with the
new array
input.value = ''; // clear the input
input.focus(); // set the focus back to the input
}
});

6. Create the displayList defined function that receives one


parameter named item.
7. Put all the code that builds a list item from the previous button
click event listener into this new displayList function and use
the item parameter as the input. A deleteChapter function will need
to be called within the delete button click event to remove the
chapter from the array and localStorage.

Example
function displayList(item) {
let li = document.createElement('li');
let deletebutton = document.createElement('button');
li.textContent = item; // note the use of the displayList
parameter 'item'
deletebutton.textContent = '❌';
deletebutton.classList.add('delete'); // this references
the CSS rule .delete{width:fit-content;} to size the delete
button
li.append(deletebutton);
list.append(li);
deletebutton.addEventListener('click', function () {
list.removeChild(li);
deleteChapter(li.textContent); // note this new function
that is needed to remove the chapter from the array and
localStorage.
input.focus(); // set the focus back to the input
});
console.log('I like to copy code instead of typing it out
myself and trying to understand it.');
}

8. Define the setChapterList function to set the localStorage


item that you have already named.
Use JSON.stringify() to stringify the array.
Example
function setChapterList() {
localStorage.setItem('myFavBOMList',
JSON.stringify(chaptersArray));
}

9. Define the getChapterList function to get the localStorage


item. No parameter is needed. Since this function returns
to an awaiting array, we will need to use JSON.parse on
the string.
Example
function getChapterList() {
return JSON.parse(localStorage.getItem('myFavBOMList'));
}

10. Finally, define the deleteChapter function with a


parameter named chapter that does three things.

- reformat the chapter parameter to get rid of the ❌ that is


passed on the end of the chapter string when we called
the deleteChapter function. Use string.slice() method to
extract the last character.

Example
chapter = chapter.slice(0, chapter.length - 1); //
this slices off the last character
- redefine the chaptersArray array using
the array.filter method to return everything except the
chapter to be removed.
Example
chaptersArray = chaptersArray.filter((item) =>
item !== chapter);

- Call the setChapterList function to update the localStorage item.

Example
function deleteChapter(chapter) {
chapter = chapter.slice(0, chapter.length - 1);
chaptersArray = chaptersArray.filter(item => item !==
chapter);
setChapterList();
}

Additional resources

1. Video: JavaScript Cookies vs localStorage vs Session Storage - Web Dev


Simplified
2. A dynamic structured approach to this activity would be to use Set object in
JavaScript. Set allows us to add and delete items from the Set object as
needed.
3. Reference: Web Storage API - MDN
4. The IndexedDB API is a more robust method of storing data on the client side
and is more like a database.
5. The Cache API is a method of storing data that is specifically used for caching
data for offline use.
Chapter 6 Final exam

Question 1
1 / 1 pts
Which of the following HTML snippet of code correctly references an
external JavaScript file name rate.js that is located is a subfolder
named scripts in HTML?

<link href="./scripts/rate.js" ></link>

<src js="scripts/rate.js"></src>

<script src="scripts/rate.js"></script>

<link href="scripts/rate.js" type="text/javascript">

Question 2
1 / 1 pts
To set the value of an element assigned to a variable identified as
"msg", you can use which of the following statements?
Check all that apply. There may be more than one correct answer.

msg.innerHTML = "You Win!";

msg.HTMLvalue = "You Win!";

msg.textValue = "You Win!";

msg.textContent = "You Win!";

msg.text = "You Win!";


Question 3
1 / 1 pts
To assign a variable identified as 'msg' an HTML document element with
a class named 'message' where this element is the first element in the
document with that class designation, which of the following would you
use?
Select all the apply.

const msg = document.getElementById('#message');

const msg = document.querySelector('#message’);

const msg = document.querySelector('message’);

const msg = document.querySelector('.message’);

const msg = document.getClassElement('message’);

Question 4
1 / 1 pts
Given the following JavaScript statement,

const msg = document.querySelector('span');

what element does this statement reference and assign to the msg
variable?

A random one from the NodeList.

An element with a class attribute of 'span'.


The first span element found on the document.

The last span element found on the document.

PartialQuestion 5
0.5 / 1 pts
In JavaScript, to assign a variable identified as 'msg' a document
element with an id named 'message', which of the following would you
use?
Select all the apply.

const msg = document.querySelector('message');

const msg = document.querySelector('#message');

const msg = document.querySelector('.message');

const msg = document.getElementById('message');

Question 6
1 / 1 pts
The following code snippet is an example of which type of function?

menubutton.addEventListener('click', () => {
menuitems.classList.toggle('show');
});

function expression

class function
arrow function

function declaration

Question 7
1 / 1 pts
Which of the following correctly sets the text node of a preselected div
element assigned to a variable identified as "reveal" as shown in this
statement?

reveal.innerHTML = `🎉 Congratulations! You are having a <strong>$


{babygender}</strong>!`;

reveal.HTMLvalue = `🎉 Congratulations! You are having a <strong>$


{babygender}</strong>!`;

reveal.textContent = `🎉 Congratulations! You are having a <strong>$


{babygender}</strong>!`;

reveal.text = `🎉 Congratulations! You are having a <strong>$


{babygender}</strong>!`;

Question 8
1 / 1 pts
The following code does not work as intended because when a valid
chapter is entered into the HTML input field with an id of "favchap" the
message on the screen is wrong saying that the favorite chapter is
something like [object HTMLInputElement]. And when they do not enter
anything into the input field, the message is still outputting the
"Thank you. your favorite chapter is [object HTMLInputElement]".
What advice would you give them?
Check all the apply.
const message = document.querySelector('#message');
const input = document.querySelector('#favchap');
if (input !== "") {
message.innerHTML = `Thank you. Your favorite chapter is ${input}.`;
} else {
message.innerHTML = `Please enter a chapter.`;
}

The HTML input element must have an id of "input" to match the


variable identifier used.

Template literal strings (`...`) cannot be used with the innerHTML


property of an element.

Reference the value property of the #favchap input element, not just
the element.

Use single quotes and not double quotes in the if block condition.

Question 9
1 / 1 pts
Which of the following is the correct way to insert a comment in
JavaScript that has more than one line?

/* This comment has more


than one line */

*** This comment has more


than one line ***

// This comment has more


than one line //

<!-- This comment has more


than one line -->
Question 10
1 / 1 pts
Which of the following will be assigned to the variable target given the
following code snippet.

let scores = [56, 78, 95, 77, 65, 86];


let target = scores.indexOf(78);

78

-1

Question 11
1 / 1 pts
Which of the following statements correctly uses a template literal
(string interpolation) instead of the string concatenation as shown?

const ward = "<strong>Unit Name</strong>: " + ward;

let ward = "<strong>Unit Name</strong>: {ward}";

const ward = `<strong>Unit Name</strong> + {ward}`;

let ward = '${<strong>Unit Name</strong>}: {ward}';


const ward = `<strong>Unit Name</strong>: ${ward}`;

IncorrectQuestion 12
0 / 1 pts
Which of the following array method statements correctly creates a new
array named 'outreach' that contains values from the scores array that
are less than 70?

const scores = [99, 88, 93, 70, 84, 69];

const outreach = scores .filter(total => total < 70);

let outreach= scores .reduce(function() { total < 70 });

const outreach= scores .map(total => total < 70);

const outreach= scores .map(function() { total < 70 });

Question 13
1 / 1 pts
Given the following object definition:

let product =
{'id':'455689A','price':23.99,'cost':15,'shelfDate':'10/01/2024'}

Which of the following statements will correctly access the value


associated with the cost key for this product variable and store it in a
variable named 'itemcost'.

let itemcost = product.cost();

let itemcost = product.cost(455689A);


let itemcost = cost.product(455689A);

let itemcost = product['cost'];

Question 14
1 / 1 pts
Given the following statements:

const section = document.createElement('section');


const h3 = document.createElement('h3');
h3.textContent = 'Relief Society';

Which of the following statements correctly adds the h3 heading with its
content to the newly created section variable?

section.innerHTML = h3;

section.h3.append;

section.appendChild(h3);

h3 += section;

Question 15
1 / 1 pts
Given this function expression that computes the wind chill factor,

const computeWindChill = function(windSpeed, temperature) {


// Fahrenheit Only
return 35.74 + (0.6215 * temperature) - (35.75 * Math.pow(windSpeed,
0.16)) + (0.4275 * temperature * Math.pow(windSpeed, 0.16));
};

Which of the following correctly calls the function using arguments


of speed and temp?
computeWindChill(speed, temp)

function computeWindChill(speed, temp)

function computeWindChill()

computeWindChill(windSpeed, temperature)

let windChill = windChill(windSpeed, temperature)

Question 16
1 / 1 pts
Given the following array definition and subsequent code,

const countries = ["Canada", "Chili", "Colombia", "Croatia", "Costa


Rica"];
const countriesLong = countries.____((country) => country.length > 7);

Which of the following keywords when used for the blank


correctly filters the countries array to a new array
named countriesLong where the country names are more than 7
characters?

filter

reduce

find

map
Question 17
1 / 1 pts
Which of the following options correctly describes the purpose of
the forEach loop?

It is used to filter elements in an array based on a specified condition.

It is used to iterate over the elements of an array and execute a


provided function for each element of the array..

It is used to sort the elements of an array in ascending or descending


order.

It is used to execute a block of code repeatedly for a specific number of


times.

Question 18
1 / 1 pts
Which JavaScript method is used to attach an event handler to an HTML
element?

addEventListener()

appendButtonChild()

querySelector()

handle()

handleEvent()
Question 19
1 / 1 pts
Given that the parent items is a CSS grid, how many columns will this
<aside> span?

aside {
border: 1px solid #eee;
padding: 2rem;
text-align: center;
grid-column: 1 / 3;
}

Question 20
1 / 1 pts
A member of your team's media query for larger views is not
working and provides you a copy of the media-query-large.css file
for review.
Which of the following feedback statements should your provide to
them?
Check all that apply.

@media screen and (min-width: 30em) {


h1 {
font-size: 2.5rem;
}
}
main {
grid-template-columns: 1fr 1fr 1fr;
}

The media query ends too soon. It does not contain all the intended CSS
rules.

You cannot use em units in media queries.

The problem is not found in the CSS file.

You must include the screen media type in the @media query.

Question 21
1 / 1 pts
Which of the following CSS selectors would correctly place a check box
in front of all the elements with a class of "check" in front of its existing
content?

.check::before { content: "✅"; }

#check:first { content: "✅"; }

div#check::content{ before: "✅"; }

.check::marker { front: "✅"; }

Question 22
1 / 1 pts
Finish this statement.
The pseudo-class is useful for declaring global CSS
variables and represents the <html> element and is identical to the
selector html, except that its specificity is higher.
html

root

specific

global

Question 23
1 / 1 pts
Select the correct answer to complete the following statement.
To apply CSS Flex, you can define a flex container using
the ______________ property on the parent element.

display: flex;

flex: 100%;

cssflex: 100%;

flex: 1 1 auto;

Question 24
1 / 1 pts
What does the : syntax in the CSS rule selector do?
Example:

a:hover {
text-decoration: overline;
}
Selects a hidden element

Selects a DOM event

Selects a pseudo-element

Selects a pseudo-class

Question 25
1 / 1 pts
Which of the following best describes the space around the
content from the CSS box model?

border

space-between

padding

paragraph

margin

IncorrectQuestion 26
0 / 1 pts
Given the following HTML markup snippet:

<ul>
<li>Unordered item</li>
<li>Unordered item
<ol>
<li>Item 1</li>
<li>Item 2</li>
</ol>
</li>
</ul>

Which of the following CSS selectors selects the outer, unordered list
items and not the embedded ordered list items?

ul + li

ul li

ul ~ li

ul > li

IncorrectQuestion 27
0 / 1 pts
Which of the following code expressions produces the last element of
any array?

array.lastIndex

array.lastIndex()

array.length - 1

array.length - 1

Question 28
1 / 1 pts
A student has this code for their responsive image. What feedback would
you give them?
Check all the apply.

<picture>
<source srcset="images/hero-small.webp" media="(min-width: 1200px)">
<source srcset="images/hero-medium.webp" media="(min-width: 800px)">
<img srcset="images/hero-large.webp" alt="Hero Photo" width="500"
height="250">
</picture>

The images are listed backwards. You should start with the hero-
small.webp file as the default when using min-width.

You are not allowed to use min-width with the <source> element's
media attribute.

Good job, the code looks good.

Your source references are missing alt attributes.

Question 29
1 / 1 pts
Which of the following would change the background color of every
other row in an HTML table?
Check all that apply.

tr:odd-rows {background-color: skyblue}

tr:nth-child(even) {background-color: skyblue}

tr:nth-child(odd) {background-color: skyblue}

tr:nth-child(:not(first)) {background-color: skyblue}


tr:even-rows {background-color: skyblue}

Question 30
1 / 1 pts
Which of the following is an accurate example of writing a comment in
CSS?

<comment>a comment</comment>

/* a comment */

// a comment

<!-- a comment -->

Question 31
1 / 1 pts
CSS is a stylesheet language used to describe the presentation of a
document written in HTML or XML.
CSS is an acronym for ___________.

Question 32
1 / 1 pts
Which of the following is the correct syntax to write a CSS shorthand
declaration to apply a top and bottom margin of 1 rem and left and
right margin of 2 rem?

margin-all: 1rem + 2rem;

margins: 1rem 2rem 1rem;

margins: 2rem;
margin: 1rem 2rem;

margin-top: 1rem; margin-right: 2rem; margin-bottom: 1rem; margin-


left:2rem;

IncorrectQuestion 33
0 / 1 pts
Choose the correct answer to make the following statement true.
In a HTML form, each field must have a ______ attribute to be submitted.
If this attribute is omitted, the data of that input field will not be sent
when the form is successfully submitted.

required

id

name

class

Question 34
1 / 1 pts
Which of the following input types would be the best choice for
displaying choices to a user if they are only allowed to
select one choice?

type="select"

type="checkbox"
type="range"

type="choice"

type="radio"

Question 35
1 / 1 pts
Given the following simple file structure within a folder:

Which of the following is the correct src reference to


the sunset.png image file from the index.html file (shown as
highlighted) located in the products sub-folder?

products/images/sunset.png

../images/sunset.png

.images/sunset.png

images/sunset.png

You might also like