Session 09 - Javascript, Part 2
Harvard Extension School
Fall 2023
Course Web Site: https://cscie12.dce.harvard.edu/
Topics
- Javascript - What can you do?
- Expanding and Collapsing Tree Structures
- Responsive Navigation
- JS Data Structures - array and "object" (key/value pair)
- Loops and Iteration
- Working with Key/Value objects and Arrays
Presentation contains 16 slides
Javascript - What can you do?
Programmatic access to all aspects of your web page!
- Manipulate classes and style properties
- Manipulate content
- Validate user input
- Communicate with Web Server (XHR, Ajax)
Getting Started with JavaScript
- MDN JavaScript
- JS Reference (DevDocs)
- W3Schools JavaScript
- Marquis, M. (2016). JavaScript for Web Designers (1st edition). A Book Apart.
- Niederst Robbins, J. (2018). Learning Web design : a beginner's guide to HTML, CSS, Javascript, and web graphics (Fifth edition.). O'Reilly.
JavaScript Review
WAIT! for DOM to be loaded
document.addEventListener("DOMContentLoaded", function(){
console.log("DOM has been loaded!");
});
Some examples will show putting the script
before the body end tag </body>
instead of setting a DOMContentLoaded
event listener on the document
Ways of Accessing the DOM
querySelector
and querySelectorAll
- Both use CSS selector syntax.
querySelector
returns only the first matchquerySelector
returns a list of items (even if it is a list of zero or one -- it returns a list!).
getElementById
This returns a single element node that we can directly operate on.
Remember that id
values must be unique, so we only get a
single match!
Expanding and Collapsing Tree Structures
- American League
- AL Central
- Chicago White Sox
- Cleveland Guardians
- Detroit Tigers
- Kansas City Royals
- Minnesota Twins
- AL East
- Baltimore Orioles
- Boston Red Sox
- New York Yankees
- Tampa Bay Rays
- Toronto Blue Jays
- AL West
- Houston Astros
- Los Angeles Angels
- Oakland Athletics
- Seattle Mariners
- Texas Rangers
- AL Central
- National League
- NL Central
- Chicago Cubs
- Cincinnati Reds
- Milwaukee Brewers
- Pittsburgh Pirates
- St. Louis Cardinals
- NL East
- Atlanta Braves
- Miami Marlins
- New York Mets
- Philadelphia Phillies
- Washington Nationals
- NL West
- Arizona Diamondbacks
- Colorado Rockies
- Los Angeles Dodgers
- San Diego Padres
- San Francisco Giants
- NL Central
Responsive Navigation
- Horizontal menu when wide screen
- Collapsed menu when small screenshot
- toggle of display of expanded menu
Responsive Navigation
- CSS to set initial state of navigation, for smaller widths and larger width screens.
- For small screen:
- set 'click' event that will toggle the menu state
- add or remove (i.e. 'toggle') a class that controls hidden or expanded.
JS Data Structures - array and "object" (key/value pair)
array Example:
['Autumn', 'Winter', 'Spring', 'Summer']
object Examples:
Simple "name/value" pairs:
{
"lastName" : "Gay",
"firstName" : "Claudine",
"email" : "president@harvard.edu"
}
"name/value" pairs, with values being an array (list) of things:
{
"apples" : ['Macoun','Empire','Honey Crisp','Albemarle Pippin'],
"oranges" : ['Naval Orange','Tangelo','Clementine','Valencia Orange']
}
And even movies
{ "movies" : [
"Casino Royale",
"Quantum of Solace",
"Skyfall",
"Spectre",
"No Time to Die"
]
}
Loops and Iteration
let oranges = ['Naval Orange','Tangelo','Clementine','Valencia Orange'];
/* Iterate with for..of */
console.log("Iterate with: item of array");
for (const myorange of oranges) {
console.log(myorange);
}
console.log("DONE!");
/* Iterate with 'classic' for (i = 0 ; i < LENGTH ; i++) */
console.log("Iterate with classic for i = ; < ; i++");
for (let i = 0; i < oranges.length; i++ ) {
console.log(i);
console.log(oranges[i]);
}
console.log("DONE!");
/* Iterate with '.forEach()' */
console.log("Iterate with forEach()");
oranges.forEach(function(myorange){
console.log(myorange);
});
console.log("DONE!");
Javascript and DOM: Building Content
And do the same for the other three seasons to get:
Javascript and DOM: Building Content
<p>
<button id="makelist" type="submit">Build List of Seasons </button>
</p>
<div id="seasonslist1">
</div>
In
script
element within head
element (<script>
):
function makeSeasonsList() {
let ul_node = document.createElement("ul");
/* Autumn */
let li_node1 = document.createElement("li");
let li_text1 = document.createTextNode("Autumn");
li_node1.appendChild(li_text1);
/* Winter */
let li_node2 = document.createElement("li");
let li_text2 = document.createTextNode("Winter");
li_node2.appendChild(li_text2);
/* Spring */
let li_node3 = document.createElement("li");
let li_text3 = document.createTextNode("Spring");
li_node3.appendChild(li_text3);
/* Summer */
let li_node4 = document.createElement("li");
let li_text4 = document.createTextNode("Summer");
li_node4.appendChild(li_text4);
/* Append the list items to the ul */
ul_node.appendChild(li_node1);
ul_node.appendChild(li_node2);
ul_node.appendChild(li_node3);
ul_node.appendChild(li_node4);
/* Place on page */
let container = document.getElementById("seasonslist1");
container.appendChild(ul_node);
}
/* Wait for DOM to be loaded, then add the click listener
to the button */
document.addEventListener('DOMContentLoaded',function(){
document.getElementById('makelist').addEventListener('click', makeSeasonsList);
});
Javascript and DOM: Building Content
Using an array (a list).
let seasons = ['Spring', 'Summer', 'Autumn', 'Winter'];
Iterate through Array
<p>
<button id="makelist" type="submit">Build List of Seasons </button>
</p>
<div id="seasonslist2">
</div>
In head
element:
<script src="example2.js"> </script>
Contents of example2.js
function makeSeasonsList() {
ul_node = document.createElement("ul");
let seasons = ['Spring', 'Summer', 'Autumn', 'Winter'];
for (let i = 0 ; i < seasons.length ; i++ ) {
let mytext = i + " " + seasons[i];
let text_node = document.createTextNode(mytext);
let li_node = document.createElement("li");
li_node.appendChild(text_node);
ul_node.appendChild(li_node);
};
let container = document.getElementById("seasonslist2");
container.appendChild(ul_node);
}
/* Wait for DOM to be loaded, then add the click listener
to the button */
document.addEventListener('DOMContentLoaded',function(){
document.getElementById('makelist').addEventListener('click', makeSeasonsList);
});
Using forEach array method
<p>
<button id="makelist" type="submit">Build List of Seasons </button>
</p>
<div id="seasonslist3">
</div>
In head
element:
<script src="example3.js"> </script>
Contents of example3.js
function makeSeasonsList() {
ul_node = document.createElement("ul");
let seasons = ['Spring', 'Summer', 'Autumn', 'Winter'];
seasons.forEach(function(s){
let text_node = document.createTextNode(s);
let li_node = document.createElement("li");
li_node.appendChild(text_node);
ul_node.appendChild(li_node);
});
let container = document.getElementById("seasonslist3");
container.appendChild(ul_node);
}
/* Wait for DOM to be loaded, then add the click listener
to the button */
document.addEventListener('DOMContentLoaded',function(){
document.getElementById('makelist').addEventListener('click', makeSeasonsList);
});
DOM methods vs innerHTML
- With DOM methods, we are creating nodes
- With
innerHTML
we are getting are setting the HTML string values.
Working with Key/Value objects and Arrays
Data:
{
"apples" : ['Macoun','Empire','Honey Crisp','Albemarle Pippin'],
"oranges" : ['Naval Orange','Tangelo','Clementine','Valencia Orange']
}
<h1>List of Fruits from Data </h1>
<div id="fruits"><!-- list goes here -->
</div>
In
script
element within head
element (<script>
):
"use strict";
let fruits = {
"apples": ['Macoun', 'Empire', 'Honey Crisp', 'Albemarle Pippin'],
"oranges": ['Naval Orange', 'Tangelo', 'Clementine', 'Valencia Orange']
};
document.addEventListener('DOMContentLoaded',function(){
buildFruitList();
});
function buildFruitList(){
let fruitList = document.createElement('ul');
for (const f in fruits) {
console.log(f);
let li = document.createElement('li');
li.appendChild(document.createTextNode(f));
if (Array.isArray(fruits[f])) {
console.log(fruits[f]);
let itemList = document.createElement('ul');
for (const item of fruits[f]) {
let li = document.createElement('li');
li.appendChild(document.createTextNode(item));
itemList.appendChild(li);
}
li.appendChild(itemList);
}
fruitList.appendChild(li);
}
document.getElementById('fruits').appendChild(fruitList);
}
JavaScript:
"use strict";
let fruits = {
"apples": ['Macoun', 'Empire', 'Honey Crisp', 'Albemarle Pippin'],
"oranges": ['Naval Orange', 'Tangelo', 'Clementine', 'Valencia Orange']
};
document.addEventListener('DOMContentLoaded',function(){
buildFruitList();
});
function buildFruitList(){
let fruitList = document.createElement('ul');
for (const f in fruits) {
console.log(f);
let li = document.createElement('li');
li.appendChild(document.createTextNode(f));
if (Array.isArray(fruits[f])) {
console.log(fruits[f]);
let itemList = document.createElement('ul');
for (const item of fruits[f]) {
let li = document.createElement('li');
li.appendChild(document.createTextNode(item));
itemList.appendChild(li);
}
li.appendChild(itemList);
}
fruitList.appendChild(li);
}
document.getElementById('fruits').appendChild(fruitList);
}