Session 09 - Javascript, Part 2

Harvard Extension School  
Fall 2023

Course Web Site: https://cscie12.dce.harvard.edu/

Topics

  1. Javascript - What can you do?
  2. Expanding and Collapsing Tree Structures
  3. Responsive Navigation
  4. JS Data Structures - array and "object" (key/value pair)
  5. Loops and Iteration
  6. Working with Key/Value objects and Arrays

Session 09 - Javascript, Part 2, slide1
Javascript - What can you do?, slide2
Getting Started with JavaScript, slide3
JavaScript Review, slide4
WAIT! for DOM to be loaded, slide5
Ways of Accessing the DOM, slide6
Expanding and Collapsing Tree Structures, slide7
Responsive Navigation, slide8
Responsive Navigation, slide9
JS Data Structures - array and "object" (key/value pair), slide10
Loops and Iteration, slide11
Javascript and DOM: Building Content, slide12
Javascript and DOM: Building Content, slide13
Javascript and DOM: Building Content, slide14
DOM methods vs innerHTML, slide15
Working with Key/Value objects and Arrays, slide16

Presentation contains 16 slides

Javascript - What can you do?

Programmatic access to all aspects of your web page!

Getting Started with JavaScript

JavaScript Review

  1. JS in HTML. Including JavaScript in HTML with script element, with either src attribute or JS code.
    <script src="scripts/site.js" ></script>
    or
    <script>
    /* JS code here */
    console.log('hello from JS!');
    </script>
  2. Variables. Declare variables with let and sometimes const.
    Though you will see the older var, but avoid that.
    You may also see const which declares a constant (a variable that won't be changed).
    let courseName = 'CSCI E-12',
      courseTerm = 'Fall 2023',
      courseInstructor = 'David' ;
  3. Console is your friend. Your browser developer tools will be critical to use, and especially the "Console". Log to the console in JS with
    console.log('hello there!');
  4. When is the code executed?script in head or right before the body close tag.
    But it is good practice to rely on specific events, especially the DOMContentLoaded event!

    The .addEventListener method takes two arguments. The first is the event name as a string, and the second is the function to execute when that event happens.

    document.addEventListener('DOMContentLoaded', function(){
        /* here's where JS goes for when DOM is loaded */
        console.log('the DOM has been loaded and parsed!');
    });
  5. Events - many are user-driven such as click, focus, blur, submit, mouseover, mouseout, keypress.
    And one important one happens when the browser has processed and loaded the HTML DOM — DOMContentLoaded.
  6. Event Listeners Added through JavaScript - use JavaScript to add event listeners!
    1. select the element(s)
    2. add event listener and function to be run when that event happens
    let expandButton = document.querySelector('#expand');
    expandButton.addEventListener('click',function(){
      /* do expand actions here */
    })
  7. Functions. Functions can be named, and they can also be anonymous (unnamed) when setting event handlers. Functions can have arguements.

    Named function that accepts an argument:

    function square(x) {
      let numberSquared = x*x;
      return numberSquared;
    }
    /* using the function */
      let x = 4;
      let y = square(x);
      /* y should be 16 */
      console.log("y is " + y);

    Anonymous functions — function() {} — are often used in setting event listeners

    document.addEventListener('DOMContentLoaded', function(){
      /* here's where JS goes for when DOM is loaded */
      console.log('the DOM has been loaded and parsed!');
    });
  8. JavaScript gives us ways to access the DOM as well as manipulate it! Some common ways of accessing the DOM are getElementById, querySelector, querySelectorAll as well as classList, classList.add, classList.remove, classList.toggle.
    We can also construct content with methods like createElement, createTextNode, appendChild, and innerHTML

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

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

Responsive Navigation

menu

menu

menu

Responsive Navigation

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"
             ]
}

Movie data with more detail.

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

DOM create nodes

And do the same for the other three seasons to get:
DOM create nodes

Javascript and DOM: Building Content

Example 9.1 - Example 9.1
 
 <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

Example 9.2 - Example 9.2
 
 <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

Example 9.3 - Example 9.3
 
 <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

Working with Key/Value objects and Arrays

Data:

{
  "apples" : ['Macoun','Empire','Honey Crisp','Albemarle Pippin'],
  "oranges" : ['Naval Orange','Tangelo','Clementine','Valencia Orange']
}
Example 9.4 - Example 9.4
 
 <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);
}