# 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)) }) }) ```