---
tags: JavaScript
description: JavaScript教學-110-2主題社課-國立中興大學資訊科學研習社
# type: slide
---
<style>
.slides img{background-color:grey!important}
.slides img[title^='"']{filter:invert(100%)}
hr, .slides [title^='*']{display:none}
summary h1{display:inline;border-bottom:0!important}
</style>
<!-- .slide: data-background="black" -->
###### [JavaScript 教學/](/@NCHUIT/js)
:::spoiler {state=open}<h1>操作網頁元素</h1>
<!-- | <i class="fa fa-fw fa-wpforms"></i>防疫表單 | <i class="fa fa-fw fa-wpforms"></i>入社表單 | <i class="fa fa-fw fa-comments-o"></i>回饋單 |
|:-:|:-:|:-:|
| [](https://forms.gle/bghmKYxjc9v7m9WE8) | [](https://reurl.cc/q1keqn) | [](http://reurl.cc/VjYNGZ) | -->
+ <i class="fa fa-book"></i> 網頁 md.nchuit.cc/js
+ <i class="fa fa-tv"></i> 簡報 md.nchuit.cc/js6
[ToC]
:::
> [name=VJ]
----
## 前情提要: `*.html` 基礎框架
```htmlmixed
<html>
<head>
<title>網頁標題</title>
<meta name="description" content="網頁描述">
<link rel="icon" href="https://hackmd.io/favicon.png">
<!--以及更多-->
</head>
<body>
網頁內容
</body>
</html>
```
你可能注意到了...
`<head>`內的元素都不需要用`</*>`關起來
###### [HTML稍微詳細的介紹: 從HTML到MarkDown(建議閱讀)](/@NCHUIT/mdhtml)
----
### 樹狀結構 DOM
[](https://www.w3schools.com/js/js_htmldom_document.asp)
----
### JavaScript 又在哪呢?
HTML 的 [`<script>`元素](https://developer.mozilla.org/zh-TW/docs/Web/HTML/Element/script)
```htmlmixed
<script>
// JavaScript 寫在這裡
</script>
```
:::info
🕹快捷鍵: 在 <i class="fa fa-fw fa-chrome"></i>Chrome 或 <i class="fa fa-fw fa-internet-explorer"></i>Edge 瀏覽器中按下 <kbd>F12</kbd> 或 <kbd>Ctrl + Shift + I</kbd> 可以在 `Elements` 頁面檢視所有 HTML 元素。
:::
----

▲ <kbd>Ctrl</kbd>+<kbd>F</kbd> 搜索 `<script>`
----
#### <i class="fa fa-fw fa-gamepad"></i>動動手: 主控台~~入侵~~
試對瀏覽器開發者工具的主控台發送以下指令:
```javascript
document.body.innerHTML="Hello"
```
:::info
🕹快捷鍵: 在 <i class="fa fa-fw fa-chrome"></i>Chrome 或 <i class="fa fa-fw fa-internet-explorer"></i>Edge 瀏覽器中按下 <kbd>F12</kbd> 或 <kbd>Ctrl+Shift+I</kbd> 可以打開瀏覽器的開發者工具,請在 `console`(`主控台`) 頁面輸入並發送指令。
:::
```javascript
onbeforeunload=()=>true
```
---
## 元素生成
> 下面要存成HTML檔案請打上2,7行
生成按鈕 `<button style="background-color: red;">我是按鈕</button>`
```htmlembedded= [|1-2,7-8]
<script>
onload = ev =>{
元素 = document.createElement("button")
document.body.appendChild(元素)
元素.innerHTML = "我是按鈕"
元素.style.backgroundColor = "red"
}
</script>
```
----

----
### 表格
學會生成表格可以幫助我們快速學會HTML架構
```htmlembedded
<table> <!--正常靜態HTML表格-->
<thead>
<tr><th>標題A</th><th>標題B</th></tr>
</thead>
<tbody>
<tr><td>欄位A1</td><td>欄位B1</td></tr>
<tr><td>欄位A2</td><td>欄位B2</td></tr>
</tbody>
</table>
```
<table>
<thead>
<tr><th>標題A</th><th>標題B</th></tr>
</thead>
<tbody>
<tr><td>欄位A1</td><td>欄位B1</td></tr>
<tr><td>欄位A2</td><td>欄位B2</td></tr>
</tbody>
</table>
----
:::spoiler 練習1: 利用 `createElement` 和 `appendChild` 生成前面的表格
```javascript=
表格 = document.createElement("table")
document.body.appendChild(表格)
表格標題 = document.createElement("thead")
表格.appendChild(表格標題)
標題列 = document.createElement("tr")
表格標題.appendChild(標題列)
標題A = document.createElement("th")
標題列.appendChild(標題A)
標題A.innerHTML = "標題A"
標題B = document.createElement("th")
標題列.appendChild(標題B)
標題B.innerHTML = "標題B"
表格內容 = document.createElement("tbody")
表格.appendChild(表格內容)
列1 = document.createElement("tr")
表格內容.appendChild(列1)
欄位A1 = document.createElement("td")
列1.appendChild(欄位A1)
欄位A1.innerHTML = "欄位A1"
欄位B1 = document.createElement("td")
列1.appendChild(欄位B1)
欄位B1.innerHTML = "欄位B1"
列2 = document.createElement("tr")
表格內容.appendChild(列2)
欄位A2 = document.createElement("td")
列2.appendChild(欄位A2)
欄位A2.innerHTML = "欄位A2"
欄位B2 = document.createElement("td")
列2.appendChild(欄位B2)
欄位B2.innerHTML = "欄位B2"
```
:::
提示
1. 只能對 `document` 用 `createElement`
2. 也可以對元素 `appendChild`
----
應用既有函式和流程控制
```javascript=
document.body.appendChild(表格 = document.createElement("table"));
表格標題列 = 表格.createTHead().insertRow();
for(const 標題文字 of ["標題A", "標題B"]){
表格標題列.appendChild(標題 = document.createElement("th"));
標題.innerHTML = 標題文字;
}
表格內容 = 表格.createTBody();
for(const 文字列 of [
["欄位A1", "欄位B1"],
["欄位A2", "欄位B2"]
]){
列 = 表格內容.insertRow();
for(const 文字欄 of 文字列)
列.insertCell().innerHTML = 文字欄;
}
```
---
### 表單
學會生成表單可以幫助我們快速學會HTML元素屬性
```htmlembedded=
<!-- 這是防疫表單,提醒大家點到 -->
<form method="post" action="https://docs.google.com/forms/u/0/d/e/1FAIpQLScGqBrda8j-PKEy8e-5vDgFxLsrSKUjgDpMqO6I8SWuj_f0XQ/formResponse">
<input placeholder="輸入學號" name="entry.1163524280" type="text" required>
<input name="帥哥美女" value="true" hidden>
<input value="提交" type="submit">
</form>
```
```htmlembedded=
<!-- 這是興大入口 -->
<form method="post" action="https://idp.nchu.edu.tw/nidp/idff/sso?sid=0&sid=0">
<input name="target" value="https://portal.nchu.edu.tw/portal" hidden>
<input placeholder="輸入學號" name="Ecom_User_ID" type="text" required><br>
<input placeholder="輸入密碼" name="Ecom_Password" type="password" required>
<input name="帥哥美女" value="true" hidden>
<input value="登入" type="submit">
</form>
```
----
哪來的?

----

----
::::spoiler 練習2: 選一個前面的表單來生成
:::spoiler 防疫表單
```javascript=
表單 = document.createElement("form")
document.body.appendChild(表單)
表單.setAttribute("method","post")
// 表單.setAttribute("target","_blank")
表單.setAttribute("action","https://docs.google.com/forms/u/0/d/e/1FAIpQLSeSdsx_EHjL3VdxKxe3gnUWgmW9GWFWkyoEk-ywRuThMW1XBQ/formResponse")
元素 = document.createElement("input")
表單.appendChild(元素)
元素.setAttribute("placeholder","輸入學號")
元素.setAttribute("name","entry.720137305")
元素.setAttribute("type","text")
元素.setAttribute("required","")
元素 = document.createElement("input")
表單.appendChild(元素)
元素.setAttribute("name","帥哥美女")
元素.setAttribute("value","true")
元素.setAttribute("hidden","")
元素 = document.createElement("input")
表單.appendChild(元素)
元素.setAttribute("value","提交")
元素.setAttribute("type","submit")
```
:::
:::spoiler 興大入口
```javascript=
表單 = document.createElement("form")
document.body.appendChild(表單)
表單.setAttribute("method","post")
// 表單.setAttribute("target","_blank")
表單.setAttribute("action","https://idp.nchu.edu.tw/nidp/idff/sso?sid=0&sid=0")
元素 = document.createElement("input")
表單.appendChild(元素)
元素.setAttribute("placeholder","輸入學號")
元素.setAttribute("name","Ecom_User_ID")
元素.setAttribute("type","text")
元素.setAttribute("required","")
元素 = document.createElement("input")
表單.appendChild(元素)
元素.setAttribute("placeholder","輸入密碼")
元素.setAttribute("name","Ecom_Password")
元素.setAttribute("type","password")
元素.setAttribute("required","")
元素 = document.createElement("input")
表單.appendChild(元素)
元素.setAttribute("name","帥哥美女")
元素.setAttribute("value","true")
元素.setAttribute("hidden","")
元素 = document.createElement("input")
表單.appendChild(元素)
元素.setAttribute("value","登入")
元素.setAttribute("type","submit")
```
:::
::::
提示: `setAttribute("屬性","屬性值")`
例如
```javascript
元素 = document.createElement("input")
document.body.appendChild(元素)
元素.setAttribute("name","帥哥美女")
元素.setAttribute("value","true")
元素.setAttribute("hidden","")
```
就生成HTML
```htmlembedded
<input name="帥哥美女" value="true" hidden>
```
---
## 事件監聽器
### 點擊 click
HTML嵌入式監聽器
```htmlembedded=
<button onclick="alert('Hello World')">
按我彈出Hello World
</button>
```
**不建議像上面這樣寫,這是在汙染標記語言**
`onclick` 屬性就是監聽器的一種
----
### 先生成再監聽
讓你可以在JS繼續操作元素,雖然冗長
```javascript=
元素 = document.createElement("button")
document.body.appendChild(元素)
元素.innerHTML = "我是按鈕"
元素.onclick = ev => alert("Hello world")
```
監聽器可以像上面直接用 `.` 接在元素後面,也可以
```javascript=
元素 = document.createElement("button")
document.body.appendChild(元素)
元素.innerHTML = "我是按鈕"
元素.addEventListener("click", ev => alert("Hello world"))
```
----
#### ev?
就是監聽器捕捉到的事件你可以 `console.log(ev)` 看看它是什麼東西
----
:::spoiler 練習: 點擊生成按鈕
```javascript=
元素 = document.createElement("button")
document.body.appendChild(元素)
元素.innerHTML = "我是按鈕"
元素.onclick = ev => {
元素 = document.createElement("button")
document.body.appendChild(元素)
元素.innerHTML = "我是另一個按鈕"
}
```
:::
----
### 按鍵 keydown
```javascript=
onkeydown = ev => {
switch(ev.key){
case "ArrowUp": /*TO-DO*/ break;
case "ArrowDown": /*TO-DO*/ break;
case "ArrowLeft": /*TO-DO*/ break;
case "ArrowRight": /*TO-DO*/ break;
}
}
```
----
### 重載頁面 beforeunload
前面的課程已經看膩了吧(?)
```javascript=
//法1
onbeforeunload = ev => true
//法2
addEventListener("beforeunload", ev => true)
```
----
### 更多
`onabort`, `onautocomplete`, `onautocompleteerror`, `onblur`, `oncancel`, `oncanplay`, `oncanplaythrough`, `onchange`, `onclick`, `onclose`, `oncontextmenu`, `oncuechange`, `ondblclick`, `ondrag`, `ondragend`, `ondragenter`, `ondragexit`, `ondragleave`, `ondragover`, `ondragstart`, `ondrop`, `ondurationchange`, `onemptied`, `onended`, `onerror`, `onfocus`, `oninput`, `oninvalid`, `onkeydown`, `onkeypress`, `onkeyup`, `onload`, `onloadeddata`, `onloadedmetadata`, `onloadstart`, `onmousedown`, `onmouseenter`, `onmouseleave`, `onmousemove`, `onmouseout`, `onmouseover`, `onmouseup`, `onmousewheel`, `onpause`, `onplay`, `onplaying`, `onprogress`, `onratechange`, `onreset`, `onresize`, `onscroll`, `onseeked`, `onseeking`, `onselect`, `onshow`, `onsort`, `onstalled`, `onsubmit`, `onsuspend`, `ontimeupdate`, `ontoggle`, `onvolumechange`, `onwaiting`
----
:::spoiler 練習: 只使用純 JavaScript,建立5×5的表格,利用按鍵監聽器「移動」紅色欄位
```javascript=
表格元素 = [
["A1", "B1", "C1", "D1", "E1"],
["A2", "B2", "C2", "D2", "E2"],
["A3", "B3", "C3", "D3", "E3"],
["A4", "B4", "C4", "D4", "E4"],
["A5", "B5", "C5", "D5", "E5"],
];
document.body.appendChild(表格 = document.createElement("table"));
表格內容 = 表格.createTBody();
i = 0;
for (const 文字列 of 表格元素) {
j = 0;
列 = 表格內容.insertRow();
for (const 文字欄 of 文字列)
(表格元素[i][j++] = 列.insertCell()).innerHTML = 文字欄;
i++;
}
現在位置 = [2,2];
表格元素[現在位置[0]][現在位置[1]].style.backgroundColor = "red";
onkeydown = ev => {
if(ev.keyCode < 37 || ev.keyCode > 40) return;
表格元素[現在位置[0]][現在位置[1]].style.backgroundColor = "unset";
switch(ev.key){ default:
break;case "ArrowUp": if(--現在位置[0] == -1) 現在位置[0] = 4;
break;case "ArrowDown": if(++現在位置[0] == 5) 現在位置[0] = 0;
break;case "ArrowLeft": if(--現在位置[1] == -1) 現在位置[1] = 4;
break;case "ArrowRight": if(++現在位置[1] == 5) 現在位置[1] = 0;
}
表格元素[現在位置[0]][現在位置[1]].style.backgroundColor = "red";
}
```
:::
示例
→
----
## 作品展示
* [2022 GiCS 刷題](https://nchuit.cc/GiCS) by [<i class="fa fa-fw fa-github"></i>VJ](https://github.com/twjmy)
* [Blackjack](https://twjmy.github.io/dynamic-web-programming/HW5-Blackjack) by [<i class="fa fa-fw fa-github"></i>VJ](https://github.com/twjmy)
* [Black Jack](https://nchuit.cc/103A_JQuery_Class/demo.html) by [<i class="fa fa-fw fa-github"></i>pastleo](https://github.com/pastleo)