# JavaScript
---
## What can JavaScript do to a web?
JavaScript 可以讓網頁有互動性!
----
* JavaScript can change all the HTML elements in the page
* JavaScript can change all the HTML attributes in the page
* JavaScript can change all the CSS styles in the page
* JavaScript can remove existing HTML elements and attributes
* JavaScript can add new HTML elements and attributes
* JavaScript can react to all existing HTML events in the page
* JavaScript can create new HTML events in the page
---
## Link to HTML
----
#### 1. Use `<script>` and `</script>` tags.
```html=
<script>
document.getElementById("demo").innerHTML = "HI";
</script>
```
###### You can place any number of scripts in an HTML document. Scripts can be placed in the `<body>`, or in the `<head>` section of an HTML page, or in both.
----
#### 2. External JavaScript
#### In HTML:
```html=
<script src="index.js"></script>
```
#### In `index.js`:
```javascript=
function myFunction() {
document.getElementById("demo").innerHTML = "Paragraph changed.";
}
```
---
## Variables
| Keyword | Description |
| ------- | ------------------------- |
| var | Declares a variable |
| let | Declares a block variable |
| const | Declares a block constant |
---

----
### `Array.forEach()`
The forEach() method calls a function (a callback function) once for each array element.
```javascript=
const numbers = [45, 4, 9, 16, 25];
let txt = "";
numbers.forEach(myFunction);
function myFunction(value, index, array) {
txt += value + "<br>";
}
```
----
### `Array.includes()`
This allows us to check if an element is present in an array (including NaN, unlike indexOf).
```javascript=
const fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.includes("Mango"); // is true
```
----
### `Array.filter()`
The filter() method creates a **new array** with array elements that passes a test.
```javascript=
const numbers = [45, 4, 9, 16, 25];
const over18 = numbers.filter(myFunction);
function myFunction(value, index, array) {
return value > 18;
}
```
----
### `Array.map()`
- creates a new array by performing a function on each array element
- <span style="color:red">does not execute the function for array elements without values</span>
- does not change the original array
```javascript=
const numbers1 = [45, 4, 9, 16, 25];
const numbers2 = numbers1.map(myFunction);
function myFunction(value, index, array) {
return value * 2;
}
```
----
### `Array.reduce()`
- The reduce() method runs a function on each array element to produce (reduce it to) <span style="color:red">a single value.</span>
- The method works from left-to-right in the array.
```javascript=
const numbers = [45, 4, 9, 16, 25];
let sum = numbers.reduce(myFunction);
function myFunction(total, value, index, array) {
return total + value;
}
```
----
### `Array.some()`
The some() method check if some array values pass a test.
```javascript=
const numbers = [45, 4, 9, 16, 25];
let someOver18 = numbers.some(myFunction); // true
function myFunction(value, index, array) {
return value > 18;
}
```
----
### `Array.every()`
The every() method check if all array values pass a test.
```javascript=
const numbers = [45, 4, 9, 16, 25];
let allOver18 = numbers.every(myFunction); // false
function myFunction(value, index, array) {
return value > 18;
}
```
----
### `Array.sort()`
1. The sort() method sorts an array alphabetically:
```javascript=
const fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.sort(); // Sorts the elements of fruits
```
----
2. By default, the sort() function sorts values as strings. You can sort numbers by providing a compare function:
```javascript=
const points = [40, 100, 1, 5, 25, 10];
points.sort(function(a, b){return a - b});
```
More usage: https://www.w3schools.com/js/js_array_sort.asp
----
### `Array.from()`
returns an Array object from any object with a length property or any iterable object.
```javascript=
Array.from("ABCDEFG") // Returns [A,B,C,D,E,F,G]
```
---
## DOM Operation
#### *Document Object Model*

###### With DOM, you can access and change all the elements of an HTML document!
----
### Finding HTML Elements
- `document.getElementById(id)`
- `document.getElementsByTagName(name)`
- `document.getElementsByClassName(name)`
----
### Changing HTML Elements
* `element.innerHTML = newHtmlContent`
* `element.attribute = newValue`
* `element.style.property = newStyle`
* `element.setAttribute(attribute, value)`
----
### Adding and Deleting Elements
* `document.createElement(element)`
* `document.removeChild(element)`
* `document.appendChild(element)`
* `document.replaceChild(new, old)`
----
### Adding Events Handlers
```javascript=
element.onclick = handleClickFunction //overwriting existing events
element.addEventListener("mouseover", handleMouseoverFunction);
element.addEventListener("click", handleClickFunction);
element.addEventListener("mouseout", handleMouseoutFunction);
```
---
## Basic Sample Code
----
### File Stucture
```bash=
class02_JavaScript
├── index.html
├── scripts
│ └── main.js
├── static
│ └── images
└── styles
```
----
`index.html`
```html=
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Title</title>
<link rel="stylesheet" href="styles/main.css" />
</head>
<body>
<p id="text">Like: 0</p>
<div class="button-container">
<button id="btn-like">Like</button>
<!-- Todo: Add new button elements with id here-->
</div>
<script src="scripts/index.js"></script>
</body>
</html>
```
----
`main.js`
```javascript=
const btnLike = document.getElementById("btn_like");
// Todo:
// Find and declare the button elements (hate/reset) to add onclick function.
const text = document.getElementById("text");
let count = 0;
btnLike.onclick = () => {
count += 1;
text.innerText = `Like: ${count.toString()}`;
};
// Todo:
// Define the onclick function for each button (hate/reset)
```
---
## Homework: Todo List
https://hackmd.io/p/HyUbwNhLV#/
> This is a homework from Ric’s Web Programming Class 2019 Spring
----
### 下載檔案
- index.html: https://pastebin.com/raw/S2ur8Vy1
- styles.css: https://pastebin.com/raw/YzzVLgdc
- todo.js: 自己寫
- 叉叉圖片:

----
試著把 todo.js 中被挖空的地方補齊!
hint:
- 對 input addEventListener, keyup (如何偵測按 enter, keycode ...)
- 也要開一個陣列存
- 新增一個 element: appendChild
解答: https://pastebin.com/raw/NvstEuW3
```javascript=
var todoData = {}
var id = 0;
var stat = "ALL"; // "ALL", "ACTIVE", "COMPLETED"
var count = 0;
const ulNode = document.getElementById("todo-list");
const removeTodo = (id) => {
count += todoData[id].checked ? 0 : -1;
document.getElementById("left_count").innerText = count;
delete(todoData[id]);
const liNode = document.getElementById(`li-${id}`);
liNode.remove();
}
const changeChecked = (id) =>{
count += todoData[id].checked ? 1 : -1;
document.getElementById("left_count").innerText = count;
todoData[id].checked = !todoData[id].checked;
}
const addNewTodo = (data)=>{
// data = {
// "id": 0,
// "task": "Testing text",
// "checked": false
// }
const {id, task, checked} = data;
const liNode = document.createElement("li");
const divNode = document.createElement("div");
const inputNode = document.createElement("input");
const labelNode = document.createElement("label");
const h1Node = document.createElement("h1");
const imgNode = document.createElement("img");
liNode.appendChild(divNode);
liNode.appendChild(h1Node);
liNode.append(imgNode);
divNode.append(inputNode);
divNode.append(labelNode);
if (stat === "COMPLETED"){
liNode.style.display = "none";
}
liNode.className ="todo-app__item";
liNode.id = `li-${id}`;
divNode.className = "todo-app__checkbox";
inputNode.type = "checkbox";
inputNode.id = id;
inputNode.checked = checked;
inputNode.addEventListener("click", ()=>changeChecked(id));
labelNode.htmlFor = id;
h1Node.className = "todo-app__item-detail";
h1Node.innerText = task;
imgNode.src = "img/x.png";
imgNode.className = "todo-app__item-x";
imgNode.id = `img${id}`;
imgNode.addEventListener("click", ()=>removeTodo(id));
ulNode.append(liNode);
count += 1;
document.getElementById("left_count").innerText = count;
}
// todoData.forEach(addNewTodo);
// Read input
const listenInput = (e) => {
if (e.key !== "Enter"){
return;
}
const task = e.target.value;
const data = {task, id, checked: false};
addNewTodo(data);
todoData[id] = {task, checked: false};
e.target.value = "";
id += 1;
}
const inputNode = document.getElementById("todo-input");
inputNode.addEventListener("keydown", listenInput);
const changeStatus = (new_stat) => {
if (stat === new_stat){
return;
}
stat = new_stat;
switch (stat){
case "ALL":
// const liNodeList = document.getElementsByClassName("todo-app__item");
// [].forEach.call(liNodeList, (Node)=>{
// Node.style.display = "flex";
// })
Object.keys(todoData).forEach((id)=>{
const {checked} = todoData[id];
const liNode = document.getElementById(`li-${id}`);
liNode.style.display = "flex";
})
break;
case "ACTIVE":
Object.keys(todoData).forEach((id)=>{
const {checked} = todoData[id];
const liNode = document.getElementById(`li-${id}`);
liNode.style.display = checked ? "none" : "flex";
})
break;
case "COMPLETED":
Object.keys(todoData).forEach((id)=>{
const {checked} = todoData[id];
const liNode = document.getElementById(`li-${id}`);
liNode.style.display = !checked ? "none" : "flex";
})
break;
default:
break;
}
}
document.getElementById("view_0").addEventListener("click", () => changeStatus("ALL"));
document.getElementById("view_1").addEventListener("click", () => changeStatus("ACTIVE"));
document.getElementById("view_2").addEventListener("click", () => changeStatus("COMPLETED"));
const removeComplete = () => {
Object.keys(todoData).forEach((id)=>{
const {checked} = todoData[id];
if (checked) {
removeTodo(id);
}
})
}
document.getElementById("clear_completed_button").addEventListener("click", removeComplete);
```
---
js 淺顯易懂教學:https://www.w3schools.com/js/default.asp
js 闖關遊戲: https://www.codecademy.com/
<style>
.reveal .slides {
text-align: left;
}
h1, h2{
text-transform: none !important;
}
</style>
https://hackmd.io/LkWnyH8HRZSVVosrrDgV1g?view
{"metaMigratedAt":"2023-06-15T12:42:29.875Z","metaMigratedFrom":"YAML","title":"JavaScript","breaks":true,"slideOptions":"{\"theme\":\"night\",\"transition\":\"slide\"}","description":"JavaScript 可以讓網頁有互動性!","contributors":"[{\"id\":\"6481d9e0-6e73-40e2-a4a1-176b5f31f0bf\",\"add\":4162,\"del\":0},{\"id\":\"3283cada-956a-4fe4-adfc-dbde9b910191\",\"add\":8265,\"del\":3292},{\"id\":\"90f81fe6-9642-4f32-9aa7-eaccec059a0f\",\"add\":128,\"del\":0},{\"id\":\"7092aa1b-8b34-4092-b91b-a2aa74b2e662\",\"add\":750,\"del\":93},{\"id\":\"a4f7cec5-0d48-4d7e-bc83-4dfab3030445\",\"add\":1240,\"del\":27}]"}