Skip to content

Latest commit

 

History

History
672 lines (450 loc) · 13 KB

lesson06.md

File metadata and controls

672 lines (450 loc) · 13 KB

JavaScript

Lesson 6 & 7: DOM


DOM


API

  • API stands for Application Programming Interface
  • An API is a set of definitions and protocols for building and integrating application software.
  • It's a contract between two parties, for example between the developer and the browser

DOM

  • DOM stands for Document Object Model
  • DOM is a programming API for HTML documents
  • It defines the logical structure of documents and the way a document is accessed and manipulated

DOM

  • But how do we use DOM?
  • document is a variable provided by browser for us: https://developer.mozilla.org/en-US/docs/Web/API/Document
  • The type of document is object.
  • document.body.style.backgroundColor is a property pointing to the backgroundColor of the style of the body of the document.

DOM - selecting HTML items

Let's create a HTML element:

<input type="text" value="hello" />

How can we access that from JavaScript?


DOM - selecting HTML items by ID

Let's give it an id attribute:

<input type="text" value="hello" id="myInput" />

DOM - selecting HTML items by ID

<input type="text" value="hello" id="myInput" />

We can now use document.getElementById():

let input = document.getElementById("myInput");

The variable input now points to our HTML input!


DOM - manipulating attributes

let input = document.getElementById("myInput");

We can access any attributes of our HTML element like a property of an object:

console.log(input.value);  // prints "hello"

DOM - manipulating attributes

let input = document.getElementById("myInput");

We can also modify the attributes:

input.value = "world"; // changed the value of the input to "world"

Exercise - DOM manipulation


Example

  • Create an empty HTML file. Add an <input>, a <button> and a <div>
  • Add a function to your JavaScript file
  • In the onclick attribute of your <button>, call that function
  • Inside your function, get the value attribute from your input
  • Set the background color of the <div> to the value of your input

Practice solution

<body>
  <input type='text' id='colorInput' />
  <button onclick='setBackground()'>Change!</button>
  <div id='myDiv'>Hello!</div>

  <script src='main.js'></script>
</body>
function setBackground() {
  let inputElement = document.getElementById("colorInput");
  let color = inputElement.value;
  let divElement = document.getElementById("myDiv");
  divElement.style.backgroundColor = color;
}

DOM defines:

  • the structure of (HTML) documents
  • the way a document is accessed and manipulated

<input type="text" value="hello" />

How can I get this input element in JavaScript?

<input type="text" value="hello" id="myInput" />
let input = document.getElementById("myInput");
input.value = "world";

Exercise

remove the value from the input field after the user presses the button.


Solution

function setBackground() {
  let inputElement = document.getElementById("colorInput");
  let color = inputElement.value;
  let divElement = document.getElementById("myDiv");
  divElement.style.backgroundColor = color;
  inputElement.value = ''; // this removes the value
}

Setting the text

If we want to add or change any text, we can use textContent

Example:

let myElement = document.getElementById("myId");
myElement.textContent = "I changed the text!";

Exercise

Change the text content of the div to the color that the user choose!


Solution

function setBackground() {
  let inputElement = document.getElementById("colorInput");
  let color = inputElement.value;
  let divElement = document.getElementById("myDiv");
  divElement.style.backgroundColor = color;
  input.value = '';
  divElement.textContent = color; // now we changed the text!
}

Okay, lets add more stuff to our small page.

We want to show all the colors that the user has chosen.

Lets start be adding an unordered list.

<body>
  <input type='text' id='colorInput' />
  <button onclick='setBackground()'>Change!</button>
  <div id='myDiv'>Hello!</div>
  <ul id='colorList'></ul>

  <script src='main.js'></script>
</body>

We can create HTML elements using document.createElement.

for this page, we want to create list item or li;

// we put the tag in the () of createElement
let itemElement = document.createElement("li");
itemElement.textContent = "I am new item!";

Try it!


Unfortunately, the element is not on the page.

We have to tell the browser where to put it.

We do that using appendChild:

let itemElement = document.createElement("li");
itemElement.textContent = "I am new item!";

let listElement = document.getElementById("colorList");
//this means add itemElement as a child of listElement
listElement.appendChild(itemElement);

We want to show the color that the user has choose in our item that we created.

What do we have to do?

itemElement.textContent = color;

Exercise

Change the background color of the item to the color!

itemElement.style.backgroundColor = color;

Exercise

When we click on an item in our list, we want to change the background color of the div to that of the item.

itemElement.onclick = function () {
  divElement.style.backgroundColor = color;
};

Quiz

What is the output? And why?

typeof document;
"object"

Quiz

How do we change the value of an input at runtime?

<input id="myInput" value="blah">
let inputElement = document.getElementById("myInput");
inputElement.value = "blubb";

How do we change the text of a div at runtime?

<div id="myDiv">Blah</div>
let divElement = document.getElementById("myDiv");
divElement.textContent = "blubb";

How do we add a child li element?

<ul id="myList"></ul>
let listElement = document.getElementById("myList");
let itemElement = document.createElement("li");
itemElement.textContent = "new item";
listElement.appendChild(itemElement);

Exercise

  1. Create the usual empty HTML and JavaScript file
  2. Remember to load your JavaScript file in the body using a <script src=""></script> tag
  3. Add one <ul id="todoList"></ul> to your HTML page
  4. In your JavaScript file, add an array of things you need to do, for example: let todoItems = [ "wash dishes", "learn JavaScript", "do sport" ];
  5. Add all the todoItems from your JavaScript Array to your <ul> using the DOM API

Solution

let todoListElement = document.getElementById("todoList");
let todoItems = [ "wash dishes", "learn JavaScript", "do sport" ];
for (let i = 0; i < todoItems.length; i++) {
    let todoElement = document.createElement("li");
    todoElement.textContent = todoItems[i];
    todoListElement.appendChild(todoElement);
}

A note about DOM event handlers

  • We already learned that HTML Elements have a onclick property.
  • We know that this property must be a function.
  • We know that we can declare functions like:
function foo() {
  console.log("foo was called");
}

A note about DOM event handlers

  • However, variables can be functions, too:
let foo = function() {
  console.log("foo was called");
}
  • What this means: Create a new variable called foo and initialize it with a function

A note about DOM event handlers

  • Variables containing a function can be used exactly like variables containing a number, array or object:
let foo = function() {
  console.log("foo was called");
}
let bar = foo;  // now foo and bar point to the same function
bar();          // prints "foo was called"

A note about DOM event handlers

  • The function can access all variables visible to it (technical term: "Closure"):
let x = 42;
let foo = function() {
  console.log("foo was called with x: " + x);
}
let bar = foo;  // now foo and bar point to the same function
bar();          // prints "foo was called with x: 42"

A note about DOM event handlers

  • So if we want to set an onclick handler:
let myClickFunction = function() { /* some code */ }
document.body.onclick = myClickFunction;
  • Or directly:
document.body.onclick = function() { /* some code */ }

Exercise

  • Can you add a onclick handler to each of your <li> elements that changes the text to strike through (e.g. wash dishes)?
  • Hint: Use the textDecoration property:
todoElement.style.textDecoration = "line-through";

Solution

let todoListElement = document.getElementById("todoList");
let todoItems = [ "wash dishes", "learn JavaScript", "do sport" ];
for (let i = 0; i < todoItems.length; i++) {
    let todoElement = document.createElement("li");
    todoElement.textContent = todoItems[i];
    todoElement.onclick = function() {
        todoElement.style.textDecoration = "line-through";
    }
    todoListElement.appendChild(todoElement);
}

Exercise

  • Can you remove the strike-through if a strike-through item is clicked?

Solution

    todoElement.onclick = function() {
        if (todoElement.style.textDecoration === "line-through") {
            todoElement.style.textDecoration = "";
        } else {
            todoElement.style.textDecoration = "line-through";
        }
    }

Getting all the children

  • HTML Elements are hierarchical:
<body>
    <ul>
        <li>Wash dishes</li>
    </ul>
</body>
  • Every HTML Element has zero or more children

Getting all the children

  • Every HTML Element has a children property:
let items = todoListElement.children;
  • The property returns an array of all direct children

Visiting all children

  • We can use a for loop to go through all children:
let items = todoListElement.children;
for (let i = 0; i < items.length; i++) {
    console.log("item: " + items[i].textContent);
}

Further Practice

  • Can you add a button "Mark all done" that strikes through all your TODO items?
  • Hint: Use the children property of your <ul> element.
  • BONUS: Add an <input> field and a <button> to dynamically add new TODO items to your <ul>

Quiz

What's the difference?

function onMyButtonClick() {
    let myElement = document.getElementById("input");
    myElement.value = 42;
}
let myElement = document.getElementById("input");
function onMyButtonClick() {
    myElement.value = 42;
}

Quiz Answer

Fist one asks for the input element every time the button is clicked, last one only once when the page loads.


The Clicking Game

For this exercise, we will make a fun clicking game.

The HTML and JS framework is ready for you in a template.

Your task is to write the functions.


Demonstration of Working Game

Don't copy the code from here, this is just to show you how the game should work

https://jsbin.com/sipacorivu/1/edit?output


Instructions

Instead of difficulties, we will all do each step, do what you can in the class and the remainder will be homework

Link to template: https://jsbin.com/mosefizupo/edit?html,js,output

Feel free to either copy this code into your editor, or write it directly in JSBin


Step 1

Update the score and the points when the click me button is clicked

complete the function:

function handleButtonClick() {
  //your code here
}

Step 2

Make single clicks worth more each time you upgrade the clicker

complete the function:

function handleUpgradeClick() {
  //your code here
}

Step 3

Make the html background black and text white when user purchases dark mode

complete the function:

function handleDarkModeClick() {
  //your code here
}

Extended Version

Make the game your own, add next functions and buttons! Fun ideas:

  1. make upgrade buttons that make your game pretty
  2. add a auto click timer
  3. add a story like in James's Career Changer Game