---
# System prepended metadata

title: iSpan 4. JavaScript - 上課筆記本 + 整理
tags: [資展國際, js]

---

# iSpan 4. JavaScript - 上課筆記本 + 整理
>* HTML	
>定義網頁的內容
>* CSS 
>定義網頁的外觀(階層樣式表)
>* <font color="crimson">JavaScript	
>定義網頁和使用者的互動</font>

w3c的 JavaScript https://www.w3schools.com/js/default.asp



<br><br><br><br>
JS命名規則可以==英文大小寫(區分大小寫)、數字、$和底線==，但禁止首字為數字
## <font color="DodgerBlue">JavaScript</font>
### <font color="mistyrose">使用前先了解 . . .</font>
* Client 和 Server會互傳資料，js 可以在客戶端先處理好部份資訊或運算，**減少Server端負荷**。
-> 客戶端的JavaScript功能要是關閉，若網頁有使用JavaScript的功能將無法運作。
:::success
:book:　google瀏覽器的設定 -> 隱私權和安全性 -> 網站設定 -> 下面內容的 JavaScript -> 可以禁止網站使用 JavaScript 。
:::

* 不常更改變動的設定適合使用 Html 撰寫， ==常變動 / 會互動的物件==適合使用 js 撰寫。
* js 在於使用==物件( Object )== ，即==屬性 Proerty==(特徵)和==方法Method==(會動的)的集合
-> 鍵值對 ( key-value ) 的集合，值為基本數據類型為屬性，為函數則為方法。

<br><br>
==HTML DOM 物件==會把HTML檔案轉換成物件，JavaScript就可以對HTML進行變化更改。

>[!IMPORTANT]學習連結：
>* [Browser Object Model](https://www.w3schools.com/js/js_window.asp)
>* [Document Object Model ( The HTML DOM Tree )](https://www.w3schools.com/js/js_htmldom.asp)
    1. DOM tree 是 DOM 的樹狀結構。
    2. 根節點為 document，代表整份 html 文件。
    3. 其他每個節點代表著元素、屬性、文本。
>* [JavaScript and HTML DOM Reference](https://www.w3schools.com/jsref/default.asp)
->　JavaScript / Window / HTML DOM 物件和 Web APIs。
    1. **瀏覽器物件模型(Browser Object Model)** 讓 JavaScript 和==瀏覽器對話==以進行操作。
    2. **文件物件模型(Document Object Model)** 讓 JavaScript 和==HTML文件對話==以進行操作。

舉 DOM 的一個例子：
&emsp;&emsp;`document.write("水箭龜");`
&emsp;&emsp;則網頁上就會出現水箭龜三個字，甚至還能賦予 html 標籤，例如：
&emsp;&emsp;`document.write("<h1>小火龍</h1>");`
&emsp;&emsp;畫面效果就會長這樣，使用 js 對 html 進行操作更改。
![image](https://hackmd.io/_uploads/S1bj-Shbke.png)

<br><br>
:::success
:book:　三個關於 `<script>` 的補充。
* JavaScript 的使用方式有兩種：
    1. 在標籤內直接寫入程式碼。
![image](https://hackmd.io/_uploads/H1mAzBnZJx.png =70%x)
    2. 嵌入外部 JavaScript 檔案。
![image](https://hackmd.io/_uploads/H1a_mB3-Jg.png)
    3. 同時使用。
    因為程式碼執行順序，會先執行嵌入的外部檔案，忽略內部文本程式碼且不執行。
* `<script>` 的放置位置妥當，才不會讓使用者覺得網頁讀取時卡頓。
-> ==程式碼執行都是由上至下==
    1. 放置在`<head>`區塊內：適合「能夠直接顯示無關運算」的程式碼。
    2. 放置在`<body>`區塊尾：適合「需要運算或和 body 內其他元素互動」的程式碼。
* 舊程式碼會看到 `<script type="text/javascript">` 的寫法
-> 舊版需要告訴瀏覽器此段代碼類型為 text/javascript，即 JavaScript 的 MIME 類型。
-> HTML5 後，`<script>` 的 type 默認為 text/javascript。
:::


<br><br>
### <font color="mistyrose">console 主控台</font>
為 BOM 的一個物件。
按下 F12 或是滑鼠右鍵後選擇檢查，主控台就在瀏覽器的開發者工具裡面。
用途為測試、追蹤錯誤、紀錄日記，是工程師開發的重要工具。
* `console.log();` 一般訊息
* `console.error();` 錯誤訊息
* `console.warn();` 警告訊息
* `console.clear();` 清空主控台
* `console.table();` 陣列
* `console.time();` 搭配 `console.timeEnd();` 可以得到包圍程式碼的耗時，比較效能。
* `console.group();` 分組(展開)
* `console.groupCollapsed();` 分組(收合)
* `console.groupEnd();` 表示分組尾端

![image](https://hackmd.io/_uploads/r10UgL2-Je.png)

<br><br>
### <font color="mistyrose">Document 文件</font>
HTML文件在==載入瀏覽器==時，就會變成一份==文件物件==。
文件物件是HTML文件的根結點(root node)。
![image](https://hackmd.io/_uploads/H18si2eGyx.png)

文件物件也是==window物件的的屬性==。
-> 所以文件物件(document object)==**既是物件也是屬性**==(property)。
-> 使用 `window.document` 或 `document` 皆可。
如果在主控台顯示內容：
![image](https://hackmd.io/_uploads/S1Vy-1-fyg.png)

* `document.write("...");` 在html內寫上訊息。
* `document.getElementById("...")` 獲取html內指定某id的元素。
:::info
:eyes:　document.getElementById("...") 就是需要和 body 內其他元素互動；
若 js 程式碼執行位置在前，則抓取目標就會為 null 。
![image](https://hackmd.io/_uploads/By7bmkZMJx.png)
:::
>[!IMPORTANT]學習連結：
>https://www.w3schools.com/jsref/dom_obj_document.asp

<br><br><br><br>
## <font color="DodgerBlue"> 變數</font>
* 變數==宣告==格式： ==變數類型 變數名;==
->例、變數宣告並賦直 `var x = "小明"; `
* 若未宣告，使用時會跳出錯誤訊息。
* 若未賦值，使用時會跳出關鍵字 undefined。
![image](https://hackmd.io/_uploads/Hk-lLFzvC.png)

<br><br>
### <font color="mistyrose">變數命名</font>
命名規則：
1. 僅限英文大小寫 ( 區分大小寫 )、數字、美元符號、底線(A-Z、a-z、0-9、$、_ )。
2. 禁止首字母為數字。
3. 禁止使用保留字 ( reserved word，也叫關鍵字 keyword )。
4. 命名方式一、底線分隔，例： stu_name_id。
5. 命名方式二、大駝峰 Upper Camel Case：StuNameId。
6. 命名方式三、小駝峰 lower Camel Case：stuNameId。
:::success
:book:　害怕使用到保留字，可以在名字前加上my ，例如： myint
:::
>[!IMPORTANT]JavaScript 保留字有哪些：
>https://www.w3schools.com/js/js_reserved.asp

<br><br>
### <font color ="mistyrose">變數類型</font>
1. var，可橫跨block，作用於==函數內==，有==hoisting特性==。
    :::success
    :book:　hoisting特性，JavaScript 編譯階段將變數和函式的宣告存入記憶體的概念，
    使函數和變量的==宣告==被==提升==到==作用域的頂部==，即使他們的實際定義位置在下面。
    例如下圖兩個程式碼，執行上是相同的。
    ![image](https://hackmd.io/_uploads/HJYPvYfDA.png)
    :::
2. let，block scope ( 區塊作用域 ) 的變數，無法橫跨大括號。
3. const，同let，特點在於==宣告時必須賦值==，之後==無法更改==，適合定義參數如 pi=3.14 等。
:::success
:book: 此處的 block 區塊形容大括號包裹的區域，例如迴圈while(){ ... }
:::


<br><br><br><br>
## <font color ="DodgerBlue">資料型別</font>
使用==typeof==關鍵字取得資料型態類型
![image](https://hackmd.io/_uploads/B1GHb6ZMyg.png)

<br><br>
### <font color ="mistyrose">String 字串</font>
* **雙引號對或單引號對**包覆即是字串。
* 一些特殊字元需要使用跳脫字元反斜線 `"C:\\temp"` -> `"C:\temp"`。
* 算術運算子**加號**遇到字串會變成字串相接的意思 `"小明"+"好帥"` -> `"小明好帥"`。
* ==Template Literalsa 模板字串==，引號改成==反引號==，使用 ==${　}== 讓文字和變數相接，除此之外還可以直接使用多行字串 (單雙引號多行字串需要用反斜線連接)。
![image](https://hackmd.io/_uploads/Bkws-5GDA.png)
![image](https://hackmd.io/_uploads/S1HFD54_R.png)

:::success
:book: 常用的跳脫字元 `\'`單引號 `\"`雙引號 `\\`反斜線 `\t`tab `\n`換行 
:::
* ==`.length`== 
    取得字串長度(幾個字元)。
* ==`.indexOf(p)`== 
    取得第一個特定字串p在字串中的位置，起始位置為0，未找到回傳-1。
* ==`.lastIndexOf(p)`== 
    取得最後一個特定字串p在字串中的位置，格式上同.indexOf()。
* ==`.split(p1,[p2])`== 
    根據指定的分隔值p1，將字串切割，回傳一個新字串陣列；p2為保留的切割數量，預設全切。
* ==`.padStart(p1,[p2])`== 
    把字串的字元數補足到p1個；用p2值取代，預設為空白。
* ==`.substring(p1,[p2])`== 
    取得字串的其中一部分，回傳為一個新字串。
    p1 設定開始位置，p2設定結束位置(==不包含==)，預設為字串長度。
    編譯時會自動把較小的數字移至p1；負數皆視為0。
* ==`.slice(p1,[p2])`== 
    同.substring()，但不會編譯時改動p1、p2位置。
    負數值 = 字串長度 + 負數值，例、`"abcde.slice(-2) //de"`。
:::success
:book: (p1,[p2])被中括號包起來的參數代表可省略。
:::

<br><br>
### <font color ="mistyrose">Number 數值</font>
1. 正數、負數、小數都是數值。
2. 數值運算常見錯誤：Infinity、-Infinity、NaN (Not a number)。
    ![image](https://hackmd.io/_uploads/HJnK55fw0.png)
3. 減乘除(- * /)的運算會==強制把字串轉型成數值==，加號例外。
* ==`Number.MAX_SAFE_INTEGER`==
    取得安全處理數字最大值。
* ==`isNaN(p)`==
    判斷數值是否為NaN。
* ==`parseInt(p)`==
    把字串轉換為數值。
* ==`.toString()`==
    把數值轉換為字串。
:::success
:book:　Number 能處理的最大範圍 -2^53到2^53之間（不含兩個端點）。
-> 超過範圍的計算就可能出現錯誤。
:::

<br><br>
### <font color ="mistyrose">Array 陣列</font>
1. 陣列使用時機：相同的資料型態（雖然 JavaScript 可以不需要相同，但還是盡量避免）。
2. 具有==一致的意義==、需要參與同樣的運算。
3. 陣列就像置物櫃一樣，透過index，可以存取物品(元素)。
4. 使用==中括號==表示==宣告陣列== 例、`var temp = [10, 20, 30];`。
5. 存放元素進陣列 `temp[3] = [40];`。
6. 從陣列取得元素 `temp[0]`。
7. ==call by reference (傳址)==。

>[!IMPORTANT]傳址和傳值
>1. call by value (傳值)：以變數為參照賦予另一個變數值，電腦會在記憶體中新增(複製)一個新值，讓後來的變數指向新的值。
>2. call by reference (傳址)：變數會指向電腦記憶體中同樣的物件，不會有新的物件在記憶體中被創造出來，此時兩個變數的更改會互相影響。
>3. 字串和數值為 call by value； 鎮列為 call by reference。
>
>![image](https://hackmd.io/_uploads/rk5jnaXvC.png)

:::info
:eyes:　列內索引值(index)起始從0開始計算。
:::
:::info
:eyes:　JavaScript 的陣列不用先宣告長度，甚至可以跳過前面元素，從後面開始設置。
:::
* ==`.length`== 
    取得陣列長度(幾個元素)。
* ==`.toString()`==
    把陣列轉換為字串。
* ==`.join(p)`==
    取得陣列轉換的字串，其中,用參數p替代。
* ==`.shift()`==
    移除陣列的第一份資料。
* ==`.pop()`==
    移除陣列的最後一份資料。
* ==`.unshift(p)`==
    增加資料p到陣列第一個位置。
* ==`.push(p)`==
    增加資料p到陣列最後一個位置。

<br><br>
### <font color ="mistyrose">Object 物件</font>
1. 物件使用時機：多個屬性和方法都是形容==同一樣東西==。
2. 物件的屬性，定義物件的特性，例如、人類物件有身高、體重等屬性。
3. 物件的方法，定義物件的行為，例如、人類物件有睡眠、進食等方法。
4. 常見的物件中，有的不會定義方法，但幾乎都會定義==屬性==。
5. 使用大括號表示宣告物件 例、 
    `var score = {
        name:"小明",
        math:80,
        english:95
    }`。
6. 物件的大括號內格式為 `{ key1:value1, key2:value2.. }`。
>物件內為**key-value鍵-值對**，設定key值(屬性名/方法名)後冒號，後面放上value值(屬性值或函數(方法))，多個設定要用逗號分隔。

>JavaScript 會自動把==key值判斷為字串類型==。
7. 使用 . 或 [　] 可以取得或新增物件內的屬性，例、
    更改數學屬性的成績 `score.math = 90;`。
    新增科學屬性的成績 `score.science = 1000;`。
    更改英文屬性的成績 `score["english"] = 90;`。
    新增國文屬性的成績 `score["chinese"] = 1000;`。

<br><br>
### <font color ="mistyrose">Boolean 布林值</font>
1. 只會有兩個值：True 或 False。
2. 常見於比較運算後回傳的結果。
3. 轉換成數值則 True為1 ， False 為0。

<br><br>
### <font color ="mistyrose">運算子</font>
* 算數運算子
    常見的加減乘除都在此類，此外還有
    1. 取餘數% 例、 `10 % 3 = 1` 、 `15 % 4 = 3`。
    2. 變數`++`，變數 = 變數 +1 的意思，例、
    ![image](https://hackmd.io/_uploads/S18euKPPC.png)
    3. `++`變數，同變數`++`，差異在於若包含在其他式子內，前者會做完式子才+1，後者做之前就+1。
    ![image](https://hackmd.io/_uploads/BJmP_twPC.png)
* 比較運算子
    評估條件，回傳 true 或者 false 值，常見有>、<、>=、<=。
    注意程式和數學常見差異。
    1. `==` ，等於，單純比值，無視資料型態，字串"10"和數值10==會==視作相等。
    2. `===`，等於，不會自動轉型，字串"10"和數值10==不會==視作相等。
    3. `!=`，不等於。
:::info
:eyes: 因為回傳為布林值，建議不要使用連續比較，例、3>2>1 會回傳 False
因為程式由左至右，(3>2)>1執行後變成 (True)>1 -> (1)>1 -> False
:::
* 邏輯運算子
    回傳 true 或者 false 值。
    1. and (&&) 條件需要同時成立的時候。
    2. or (||) 條件擇一成立。
    3. 若確定結果程式會直接返回不會繼續判斷，像是 A&&B(A為假)	A||B(A為真)。
    
* 三元運算子
    (condition) ? value1:value2，即 (條件|比較) ? 成立執行這段 : 不成立執行這段。
    例、`(皮包的錢超過100)? 買一杯手搖 : 回家;` 

<br><br><br><br>
## <font color="DodgerBlue">內建函數</font>

### <font color="mistyrose">JavaScrip 內建函數</font>
1. Date 日期物件
    生成日期物件，隨參數不同有九種生成方式。
    ![image](https://hackmd.io/_uploads/HksAiyvfke.png)
    * ==`d.getFullYear()`== 
    取得年份 ( yyyy ) 。
    * ==`d.getMonth()`== 
    取得月份 ( 0 - 11 ) 。
    * ==`d.getDate()`== 
    取得日期 ( 1 - 31 ) 。
    * ==`d.getDay()`== 
    取得星期 ( 0 - 6 ) 。
    * ==`d.getHours()`== 
    取得小時 ( 0 - 23 ) 。
    * ==`d.getMinutes()`== 
    取得分鐘 ( 0 - 59 ) 。
    * ==`d.setdate( p )`== 
    設置日期 ( 1 - 31) 。
    * ==`d.setMonth( p )`== 
    設置月份 ( 0 - 11 ) 。
:::info
:eyes: 只有日期是從1開始數，所以使用月份要記得+1，星期則是0代表星期日。
:::
:::success
:book: 雖然日期限定填入1-31的數字，但0其實會換算成上個月的最後一天。
:::
:::success    
:book: 日期物件相減可以得到時間差，但單位是毫秒。
:::
>[!IMPORTANT]學習連結：
>https://www.w3schools.com/js/js_date_methods.asp

2. Math 數學物件
    * ==`Math.random()`== 
    產生亂數，值為 0~1 ( 不包含1 )。
    * ==`Math.ceil(x)`== 
    數值x無條件進位。
    * ==`Math.floor(x)`== 
    數值x無條件捨去。
    * ==`Math.round(x)`== 
    數值x四捨五入。
>[!IMPORTANT]學習連結：
>https://www.w3schools.com/js/js_math.asp

<br><br>
### <font color="mistyrose"> Window 內建函數</font>
window 在 JavaScript 為全域物件，所以使用屬性和方法==可以省略== window。
> 所以前面 document 章節，才會說 window.document 可以省略為 document。
* ==`window.alert(...);`== 
    訊息框，內文可以放數值、字串、陣列、變數...等。
    ![image](https://hackmd.io/_uploads/B1Oh4CDPR.png)
* ==`window.confirm(...) `== 
    確認框，一樣可以放內文，會返回 True / False。
    ![image](https://hackmd.io/_uploads/S10H4AvvA.png)
* ==`prompt(...);`== 
    輸入框，一樣可以放內文，會返回使用者輸入值的==字串==，取消則顯示null。
    ![image](https://hackmd.io/_uploads/HJBeSAPD0.png)
* ==`setInterval(p1,p2)`== 
    定義一個==重複計時器==，固定延遲了某段時間之後，才執行對應的程式碼，然後不斷循環。
    p1放入函數變數 (無小括號)、函數變數的字串 (有小括號) 或整個函數。
    p2放入隔多少毫秒執行一次，注意單位是毫秒。
    :::info
    :eyes:　p1不能直接放入 `Hi()` ， 函數的==小括號代表立即執行==。
    若放入`Hi()`則立即執行，會導致循環時`Hi()`已執行完畢，內容為空，不會重複執行。
    :::
* ==`clearInterval(p);`== 
    清除使用的 setInterval， p 要放上 setInterval()的變數或函數。
* ==`setTimeout(p1,p2)`== 
    格式和用法同setInterval，不過只做一次，適合跳轉頁面。
    :::success
    :book: 使用document.location.href = "..." 更新網址。
    :::
* ==`window.getComputedStyle( p1 ).getPropertyValue( p2 )`==
     取得指定元素某項樣式的內容 ( 所有樣式來源皆計算 )。
     p1 為HTML元素，p2 為樣式屬性。
>[!IMPORTANT]學習連結：
>https://www.w3schools.com/jsref/obj_window.asp


<br><br>
### <font color="mistyrose">DOM 文件物件模型的內建函數</font>
* ==`document.getElementsByTagName("p")`== 
    取得所有 p 標籤元素。
* ==`document.getElementsByClassName("p")`== 
    取得擁有 p class 類別的元素。
* ==`document.getElementById("p")`== 
    取得 id 為 p 的元素。
    :::info
    :eyes:　前兩個回傳值為HTMLCollection，為類陣列；
    而 getElementById 的 element 沒有加 s，回傳為 HTMLElement。
    :::
前三個範例：
![image](https://hackmd.io/_uploads/rkzyNrDG1x.png)
* ==`HTMLElement.innerText="..."`== 
    設定內容，只能純文字。
* ==`HTMLElement.innerHTML="..."`== 
    設定內容，可以包含標籤變化。
* `HTMLElement.屬性`
    設定標籤的屬性，例如 img元素設定 src 屬性；
    若為非合法屬性則無效果。
* `HTMLElement.style.樣式屬性`
    設定元素的==行內樣式==；
    若 CSS 屬性為複合字，需要改成小駝峰形式，例如 font-size 成 fontSize。
    ![image](https://hackmd.io/_uploads/SkGxmQdfyl.png)
    :::success
    :book:　和`window.getComputedStyle( p1 ).getPropertyValue( p2 )`差異在於
    一個為行內樣式，一個為最終樣式。
    :::
* ==`document.querySelector("#myId")`== 
    透過 CSS Selectors 取得一個標籤元素。    
* ==`document.querySelectorAll(".myGroup")`== 
    透過 CSS Selectors 取得全部標籤元素，回傳為 ==NodeList==。
:::info
:eyes:　有些方法是針對 ==HTMLElement==，如果取得為 HTMLCollection 或 NodeList ，要指定陣列的哪個元素。
:::
* ==`document.createElement("p")`== 
    新增p標籤的元素。
* ==`document.createTextNode("...")`== 
    新增一個文字節點。
* ==`HTMLElement.setAttribute("屬性名稱", "屬性值")`== 
    對元素設定屬性。
* ==`Node1.appendChild( Node2 );`== 
    將 Node2 附加到 Node1 上。
* ==`Node1.insertBefore( Node2 , Node3 )`== 
    在父節點 Node1 下 Node3 節點前插入新節點 Node2。
:::success
:book: Node，為 The HTML DOM Tree of Objects 上面的一個節點；常見的節點有
1. 文檔節點：根節點。
2. 元素節點：HTML 元素。
3. 文本節點：純文本內容。
4. 屬性節點：HTML 元素的屬性。
:::
>[!IMPORTANT]學習連結：
>https://www.w3schools.com/js/js_htmldom_elements.asp

<br><br><br><br>
## <font color="DodgerBlue">流程控制</font>
判斷式內需要為==布林值==。
undefined、null、0、""、NaN 會視為False。 

<br><br>
### <font color="mistyrose">if_else判斷</font>
1. 由上而下逐一確認條件，條件符合就進入執行該區域程式。
2. 執行完對應條件的程式後會直接跳出整個if判斷式。

![image](https://hackmd.io/_uploads/H18iwluDR.png)

<br><br>
### <font color="mistyrose">switch_case判斷</font>
1. 找尋 case 名稱中和expression一樣的，執行該區域。
2. 會==判斷資料型態==，注意 expr 和 case 的資料型態，例、 "10"和10。
3. 關鍵字`break` 會跳出迴圈。

![image](https://hackmd.io/_uploads/SJh3vg_wR.png)
:::info
:eyes:　若沒有break，則執行完對應區域後會繼續執行下個區域。
所以可以視情況合併條件處理，例如周一到周五上班，周末放假可以寫成如下：
![image](https://hackmd.io/_uploads/BJfrdmdG1x.png)
:::

<br><br>
### <font color="mistyrose">while迴圈</font>
1. 當滿足條件時進入迴圈，迴圈結束後會再次確認條件，直至離開迴圈。
2. 離開 while 敘述句的方式：break 或者條件不成立。

![image](https://hackmd.io/_uploads/SJAcueODC.png)

<br><br>
### <font color="mistyrose">for迴圈</font>
1. for ==迴圈執行前==執行 statement 1，為宣告變數給初始值。
2. 執行==每次== for 迴圈==前==執行 statement 2，為結束判斷式。
3. 執行==每次== for 迴圈==後==執行 statement 3，為變數累進。
![image](https://hackmd.io/_uploads/rklx9euDC.png)
:::success
:book:不同於`break`是跳出迴圈，關鍵字`continue` 是結束當前迴圈，執行下一輪迴圈
:::

<br><br><br><br>
## <font color="DodgerBlue">function 函數</font>
![image](https://hackmd.io/_uploads/HJrq1WuPC.png)
1. 參數可以為空；若要求複數參數，用,隔開。
2. 給予不對應的參數數量或資料類型，可能會有 undefined、意外結果等等。
3. 回傳值可以為空，若有回傳值則限一，且馬上回傳並終止函數，即`return`以下程式==不會執行==。
4. 函數具有 ==hoisting== 的性質，不同於 var 變數，本身的定義內容也會抬升。


<br><br>
### <font color="mistyrose">函數運算式</font>
1. 宣告函數同時宣告一個變數並賦值。
2. 因為馬上賦值變數，不用再給函數做命名。
3. 失去 hoisting 特性(因為此時為 var的 hoisting ，但尚未賦值)。
![image](https://hackmd.io/_uploads/S1O4-bOw0.png)

<br><br>
### <font color="mistyrose">事件屬性</font>
1. button有一個`onclick`屬性，設定後可以和function做連結，代表按下後執行對應函數。
![image](https://hackmd.io/_uploads/SJs9R7uG1x.png)
2. 可以在js設定 `HTMLElement.onclick = 函數名稱;`。
3. 或是設定 `HTMLElement.addEventListener('click', 函數名稱);`。
:::success
:book: 這裡函數名稱後面不能加上小括號()，因為是點擊才執行，若加上會立即執行。
:::

>[!IMPORTANT]學習連結：
>https://www.w3schools.com/js/js_functions.asp
>https://www.w3schools.com/js/js_events_examples.asp
>寫在標籤內的事件，例如 onclick。
>https://www.w3schools.com/js/js_htmldom_eventlistener.asp
>事件監聽器 addEventListener，也是==最推薦==的使用方式。



|            | HTML屬性                       | 事件監聽器                         |
| ---------- | ------------------------------ | ---------------------------------- |
| 多個事件   | 限定一個，會被覆蓋             | 可以綁定多個事件                   |
| 事件監聽器 | 寫在HTML標籤內，維護性擴展性差 | 和HTML結構分開，邏輯皆在 js 內處理 |

`HTMLElement.onclick = 函數名稱;` 為屬性，所以會覆蓋。
`HTMLElement.addEventListener('click', 函數名稱);` 為函數，不會有覆蓋問題。