Lesson 6 & 7: DOM
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
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
- 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.
Let's create a HTML element:
<input type="text" value="hello" />
How can we access that from JavaScript?
Let's give it an id
attribute:
<input type="text" value="hello" id="myInput" />
<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!
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"
let input = document.getElementById("myInput");
We can also modify the attributes:
input.value = "world"; // changed the value of the input to "world"
- Create an empty HTML file, add an
<input>
element and give it anid
attribute - Create a JavaScript file. Use
document.getElementById()
to get your input element - Look at the properties of the HTML Input: https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement
- Try to set / get a few
- 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
<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";
remove the value from the input field after the user presses the button.
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
}
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!";
Change the text content of the div to the color that the user choose!
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;
Change the background color of the item to the color!
itemElement.style.backgroundColor = color;
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;
};
What is the output? And why?
typeof document;
"object"
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);
- Create the usual empty HTML and JavaScript file
- Remember to load your JavaScript file in the body using a
<script src=""></script>
tag - Add one
<ul id="todoList"></ul>
to your HTML page - In your JavaScript file, add an array of things you need to do, for example:
let todoItems = [ "wash dishes", "learn JavaScript", "do sport" ];
- Add all the
todoItems
from your JavaScript Array to your<ul>
using the DOM API
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);
}
- 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");
}
- 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
- Variables containing a function can be used exactly like variables containing a
number
,array
orobject
:
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"
- 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"
- 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 */ }
- 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";
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);
}
- Can you remove the strike-through if a strike-through item is clicked?
todoElement.onclick = function() {
if (todoElement.style.textDecoration === "line-through") {
todoElement.style.textDecoration = "";
} else {
todoElement.style.textDecoration = "line-through";
}
}
- HTML Elements are hierarchical:
<body>
<ul>
<li>Wash dishes</li>
</ul>
</body>
- Every HTML Element has zero or more children
- Every HTML Element has a children property:
let items = todoListElement.children;
- The property returns an array of all direct 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);
}
- 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>
What's the difference?
function onMyButtonClick() {
let myElement = document.getElementById("input");
myElement.value = 42;
}
let myElement = document.getElementById("input");
function onMyButtonClick() {
myElement.value = 42;
}
Fist one asks for the input
element every time the button is clicked, last one only once when the page loads.
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.
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
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
Update the score and the points when the click me button is clicked
complete the function:
function handleButtonClick() {
//your code here
}
Make single clicks worth more each time you upgrade the clicker
complete the function:
function handleUpgradeClick() {
//your code here
}
Make the html background black and text white when user purchases dark mode
complete the function:
function handleDarkModeClick() {
//your code here
}
Make the game your own, add next functions and buttons! Fun ideas:
- make upgrade buttons that make your game pretty
- add a auto click timer
- add a story like in James's Career Changer Game