---
# System prepended metadata

title: JS (Day3)

---

# JS (Day3)

filter範例 (找出大於3的數字)

```javascript=
const list = [1, 2, 3, 4, 5];

let result = list.filter(function (a) {
  return a > 3;
});

console.log(result);

```

filter收集結果,map收集並產生陣列


## reduce 
reduce(function(累加值,目前))



將一個累加器及陣列中每項元素（由左至右）傳入回呼函式，將陣列歸納成單一值。

fn每輪的return會變成下一輪的累加值(acc)

acc若沒給初始值會將陣列中第一個元素當初始值，並少執行一圈

範例(沒給初始值)

```javascript=
const list = [1, 2, 3, 4, 5];
let a = list.reduce(function (acc, cv) {
  return acc + cv;
}; 
console.log(a);

```
![](https://i.imgur.com/306BPdB.png)

範例(給初始值)
```javascript=
const list = [1, 2, 3, 4, 5];
let a = list.reduce(function (acc, cv) {
  console.log(acc, cv);
  return acc + cv;
}, 10); //acc的初始值
console.log(a);

```
![](https://i.imgur.com/ev4w0iG.png)

範例(找出最大的數)
* fn每輪的return會變成下一輪的累加值(acc)
```javascript=
const list = [19, 23, 3, 2, 24];
let a = list.reduce(function (acc, cv) {
  //第一輪 acc → 19
  //第一輪 cv → 23
  console.log("acc=", acc, "cv=", cv);
  if (cv > acc) {
    return cv;
  } else {
    return acc;
  }
});
console.log(a);

```

![](https://i.imgur.com/WxHr8Pt.png)

---

## Object 物件

物件 = 屬性(properties) + 行為(method)
```javascript=
let cat = {
  age: 2,
  name: "meow",
  attack: function () {
    console.log("gogo!!");
  },
};

console.log(cat.age);
console.log(cat.name);
console.log(cat);
cat.attack();
```

![](https://i.imgur.com/iF6ObiX.png)


加屬性

```javascript=
let cat = {
  age: 2,
  name: "meow",
  attack: function () {
    console.log("gogo!!");
  },
};

cat.color = "red"; //新增color屬性到Cat物件中
```

delete 去除屬性

```javascript=
let cat = {
  age: 2,
  name: "meow",
  attack: function () {
    console.log("gogo!!");
  },
};

delete cat.age; //刪除cat物件中age的屬性
```

---

## DOM (Document Object Model)
將頁面透過瀏覽器物件化，用JS來抓取並控制這些物件

### getElementById 

getElementById


    <div id="cc" class="xx">123</div>


```javascript=
const c = document.getElementById("cc");

console.log(c);

```
![](https://i.imgur.com/ImcEasR.png)

### getElementsByClassName 
抓取所有class一樣的物件

<ul id="list">
     <li class="item">1</li>
     <li class="item">2</li>
     <li class="item">3</li>
</ul>

```javascript=
const c = document.getElementsByClassName("item");
console.log(c);

```
![](https://i.imgur.com/4sxUA5H.png)





### querySelector 
```htmlembedded=
<div id="cc" class="xx">123</div>

```

```javascript=
const c = document.querySelector("#cc");
console.log(c);
```

可以運用CSS選取器
範例(抓取第三個li):


<ul id="list">
     <li class="item">1</li>
     <li class="item">2</li>
     <li class="item">3</li>
</ul>


```javascript=
const b = document.querySelector("#list :last-child");
console.log(b);

```


### querySelectorAll 

```javascript=
const c = document.querySelectorAll(".item");

console.log(c);

```

![](https://i.imgur.com/rrM4WnG.png)


:::warning
HTMLCollection和NodeList都不是陣列，但NodeList比HTMLCollection多一個forEach可以運用
![](https://i.imgur.com/FoKMPpU.png)

:::

練習
將原本的內容印出五倍長


<ul id="list">
      <li class="item">1</li>
      <li class="item">2</li>
      <li class="item">3</li>
</ul>
    

```javascript=
const items = document.querySelectorAll(".item");

items.forEach(function (item) {
  item.textContent = item.textContent.repeat(5);
});

console.log(items);


```
---

### textContent vs innerHTML

前者是單純字串，後者是可以加入標籤或是添加屬性

```javascript=
const item = document.querySelector("#test");

item.innerHTML = "<h1>444</h1>";

```

### JS 添加屬性方式

```javascript=
item.style.color = "red";

```

```javascript=
item.style["color"] = "red";
```

### 抓取CSS宣告的屬性，直接新增到HTML tag中

add 增加class
remove 移除class

     <h1 id="test" class="xx">123</h1>

```css=
      .hi {
        color: white;
        background-color: red;
      }
```
```javascript=
const item = document.querySelector("#test");

item.classList.add("hi"); //改remove就是移除hi

```

綜合練習(讓奇數的li 套用hi)
    <ul id="list">
      <li class="item">1</li>
      <li class="item">2</li>
      <li class="item">3</li>
      <li class="item">4</li>
      <li class="item">5</li>
    </ul>
    
```css=
.hi {
    color: white;
    background-color: red;
}
```

```javascript=
const items = document.querySelectorAll(".item");

items.forEach(function (item, idx) {
  if (idx % 2 === 0) {
    item.classList.add("hi");
  }
});

```

---

## Event 事件

1. JS事件發生在瀏覽器的事件(resize the screen, scroll, click)
2. JS Event發生時，需要event listener了解JS Event的細節.

### addEventListener

先選擇在監聽

addEventListener(event type, callback)

event type: resize the screen, scroll, click...
callback function : parameter

同一個物件可以加N個監聽器

#### click event

```javascript=
document.addEventListener("click", function () {
  console.log("點了");
});

```

#### 將事件添加到物件中
(點擊123的時候觸發click event)

    <h1 id="test" class="text123">123</h1>
    
```javascript=
const c = document.querySelector(".text123");

c.addEventListener("click", function () {
  console.log("點了");
});

```
將function另外寫，當成值丟進去

```javascript=
const h = document.querySelector(".text123");

const text = function () {
  console.log("HIHI123");
};

h.addEventListener("click", text);
```


### 設置讀取完介面再執行JS方法

1. 若JS文件讀取不是在下方，同時又不能更改HTML文件內容時，可設置此指令再JS外圍，用意為先讓DOM的內容讀取完再執行JS。

```javascript=
 document.addEventListener("DOMContentLoaded", function () { JS程式 })
```

2. 在後面加上defer做延遲
```javascript=
<script src="./app.js" defer></script>
```

## 高階函數(式) Higher-Order Function

1. 接別的函數當參數/引數
2. 可以回傳一個函數

---

## 防止預設行為

防止物件預設行為，像是右鍵選單,超連結跳轉，表單送出

```javascript=
const btn = document.querySelector(".btn");

btn.addEventListener("click", function (e) {
  e.preventDefault();
  console.log("hi");
});

```
---

#### SRP = Single Resposibility Principle

---

Event 練習

練習一:簡易計數器(不能小於0)
```
  <button id="minus">-</button>
  <input type="number" id="counter" value="1">
  <button id="plus">+</button>
```

```javascript=
document.addEventListener("DOMContentLoaded", function () {
  const plus = document.querySelector("#plus")
  const minus = document.querySelector("#minus")
  const num = document.querySelector("#counter")

  plus.addEventListener("click", () => {
    num.value++
  })

  minus.addEventListener("click", () => {
    if (num.value > 0) {
      num.value--
    }
  })
})

```

練習二(計算BMI)

![](https://i.imgur.com/gFv4hCf.png)


```javascript=
document.addEventListener("DOMContentLoaded", function () {
  const h = document.querySelector("#bodyHeight")
  const w = document.querySelector("#bodyWeight")
  const result = document.querySelector("#resultText")

  const btn = document.querySelector("button")
  btn.addEventListener("click", function () {
    let height = h.value / 100
    let weight = w.value
    let BMI = Number(weight) / (Number(height) * Number(height))
    result.textContent = String(BMI.toFixed(2))
  })
})

```