WDD 131 Dynamic Web Fundamentals
WDD 131 Dynamic Web Fundamentals
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
"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!
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.
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);
}
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>
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.
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
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.
Overview
Variables are used to store values. Two kind of values:
Primitive values Objects
Number Function
String Class
Boolean Literal objects
Null
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;
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;
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;
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"
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
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."
<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?
// ***************************************
// 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
JS
const today = new Date();
currentyear.innerHTML = `<span>${today.getFullYear()}</span>`;
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;
}
Result
Chapter 2 CSS media queries, JavaScript Constructs, The
Document Object Model (DOM) interface, Handling DOM
effects, Responsive Menus, JavaScript debugging
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;
}
}
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
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;
}
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.
if (condition) {
// Code to execute if the condition is true
}
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 (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.
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
});
= 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
^= x ^= y x=x^y
|= x |= y 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.
== equal to x == 8 false
x == 5 true
x == "5" true
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:
|| or (x == 5 || y == 5) is false
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"
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;
}
Case Value
2 < 12 true
2 == "John" 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.
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.
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.
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;
}
btn.addEventListener("click", () => {
const musicTypes = document.selectForm.musicTypes;
console.log(`You have selected ${countSelected(musicTypes)} option(s).`);
});
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);
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 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";
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 };
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]);
}
}
// 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>
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>
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);
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.",
);
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>
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.",
);
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.
const deleteButton =
document.createElement('button');
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 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/
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);
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;
}
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
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
);
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
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:
`<li ${task.completed ?
'class="strike"' : ""}>
<p>${task.detail}</p>
<div>
<span data-
function="delete">❎</span>
<span data-
function="complete">✅</span>
</div>
</li>`;
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);
}
}
button.addEventListener('click', function() {
// Code to execute when the button is clicked
});
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.
console.log(greeting);
// Expected output: " Hello world! ";
console.log(greeting.trim());
// Expected output: "Hello world!";
JS
const str = " foo ";
console.log(str.trim()); // 'foo'
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";
}
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');
});
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.
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.
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
Typography
What is the optimal font size?
16 px is the optimal font size.
How many point sizes are recommended?
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.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> }
</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.
<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>
<div>
<p>This is some text.</p>
<p>This is some text.</p>
</div>
</body>
</html>
<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>
</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>
</body>
</html>
Use of :focus
<!DOCTYPE html>
<html>
<head>
<style>
input:focus {
background-color: yellow;
}
</style>
</head>
<body>
</body>
</html>
<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>
<p>You can use the ::first-letter pseudo-element to add a special effect to the
first character of a text!</p>
</body>
</html>
</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:
p::first-line {
color: #0000ff;
font-variant: small-caps;
}
</style>
</head>
<body>
</body>
</html>
<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>
<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>
<!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>
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
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>
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
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
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
reverse() toReversed()
shift() slice(1)
sort() toSorted()
splice() toSpliced()
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'
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.4 CONSTRUCTOR
Array()
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.
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
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
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
Accessing:
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]);
}
console.log(mycar.make); /
/ "Honda"
myFunc(mycar);
console.log(mycar.make); /
/ "Toyota"
As follows:
const square = function (number) {
return number * number;
};
console.log(square(4)); // 16
console.log(factorial(3)); // 6
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) {
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);
}
}
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
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";
console.log(multiply()); // 60
function add() {
return `${name} scored ${num1 + num2}`;
}
return add();
}
console.log(test.func());
// Expected output: 42
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
Operators/this
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 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.
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.
Reference the value property of the #favchap input element, not just
the element.
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;
Using the textContent property is the only option when working with
HTML list item content.
Either property will work in this case given that the item variable is a
simple string.
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?
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?
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.
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?
…
</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> </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> </td>
<td> </td>
<td>German</td>
<td>Dutch</td>
<td> </td>
<td> </td>
</tr>
<tr>
<th>2nd period</th>
<td>English</td>
<td>English</td>
<td> </td>
<td>German</td>
<td>Dutch</td>
<td> </td>
<td> </td>
</tr>
<tr>
<th>3rd period</th>
<td> </td>
<td>German</td>
<td> </td>
<td>German</td>
<td>Dutch</td>
<td> </td>
<td> </td>
</tr>
<tr>
<th>4th period</th>
<td> </td>
<td>English</td>
<td> </td>
<td>English</td>
<td>Dutch</td>
<td> </td>
<td> </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>
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>
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.
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,
};
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]}.`);
},
};
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",
},
// …
};
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
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}.`);
},
};
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."
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}.`);
};
}
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.
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.
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.
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.
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.
Parameters:
callbackFn
element
index
array
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
element
index
array
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
// 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
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
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:
[].reduce(getMax); // TypeError
array.reduce(reducer);
The callback would be invoked four times, with the arguments and return
values in each call being as follows:
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:
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);
// Usage
multiply6(6); // 36
multiply9(9); // 81
multiply16(16); // 256
multiply24(10); // 240
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
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,
};
}, {});
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;
}
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.
JSCopy to Clipboard
const flattened = array.reduce((acc, cur) => acc.concat(cur), []);
JSCopy to Clipboard
const flattened = array.flat();
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);
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);
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));
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];
});
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);
What are the best situations for using array reduce 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>©<span id="currentyear"></span> | Carlos Medina |
Bolivia</p>
<p>Last Modification: <span id="lastModified"></span></p>
</footer>
</body>
</html>
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;
}
footer {
text-align: center;
background-color: #e24b05;
height: 4rem;
align-content: center;
color: white;
}
footer p {
padding: 0.2rem;
}
p {
padding: 1.5rem;
}
.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);
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.
Form settings:
Variable Description
$theme-form-font-family Font family of the form.
HTML
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="description" content="Fill Me In">
<meta name="author" content="John Doe">
<!-- 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">
</head>
<body>
<!-- HEADER HERE -->
<header>
<h1>Course Proposal</h1>
<h2>Designing Web Forms</h2>
</header>
<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 ▾</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>
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%;}
/*-------------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;
}
Result
5.2 Callback functions
doSomething(() => {
value = 2;
});
console.log(value);
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.
}
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 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.
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
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:
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.
Example
const input = document.querySelector('#favchap');
const button = document.querySelector('button');
const list = document.querySelector('#list');
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.
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.');
}
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);
Example
function deleteChapter(chapter) {
chapter = chapter.slice(0, chapter.length - 1);
chaptersArray = chaptersArray.filter(item => item !==
chapter);
setChapterList();
}
Additional resources
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?
<src js="scripts/rate.js"></src>
<script src="scripts/rate.js"></script>
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.
Question 4
1 / 1 pts
Given the following JavaScript statement,
what element does this statement reference and assign to the msg
variable?
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.
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?
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.`;
}
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?
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?
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?
Question 13
1 / 1 pts
Given the following object definition:
let product =
{'id':'455689A','price':23.99,'cost':15,'shelfDate':'10/01/2024'}
Question 14
1 / 1 pts
Given the following statements:
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,
function computeWindChill()
computeWindChill(windSpeed, temperature)
Question 16
1 / 1 pts
Given the following array definition and subsequent code,
filter
reduce
find
map
Question 17
1 / 1 pts
Which of the following options correctly describes the purpose of
the forEach loop?
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.
The media query ends too soon. It does not contain all the intended CSS
rules.
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?
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 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.
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.
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
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?
margins: 2rem;
margin: 1rem 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:
products/images/sunset.png
../images/sunset.png
.images/sunset.png
images/sunset.png