JavaScript 教學/

操作網頁元素

VJ


前情提要: *.html 基礎框架

<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(建議閱讀)

樹狀結構 DOM


JavaScript 又在哪呢?

HTML 的 <script>元素

<script>

  // JavaScript 寫在這裡

</script>

🕹快捷鍵: 在 Chrome 或 Edge 瀏覽器中按下 F12Ctrl + Shift + I 可以在 Elements 頁面檢視所有 HTML 元素。



Ctrl+F 搜索 <script>


動動手: 主控台入侵

試對瀏覽器開發者工具的主控台發送以下指令:

document.body.innerHTML="Hello"

🕹快捷鍵: 在 Chrome 或 Edge 瀏覽器中按下 F12Ctrl+Shift+I 可以打開瀏覽器的開發者工具,請在 console(主控台) 頁面輸入並發送指令。

onbeforeunload=()=>true

元素生成

下面要存成HTML檔案請打上2,7行

生成按鈕 <button style="background-color: red;">我是按鈕</button>

<script> onload = ev =>{ 元素 = document.createElement("button") document.body.appendChild(元素) 元素.innerHTML = "我是按鈕" 元素.style.backgroundColor = "red" } </script>


表格

學會生成表格可以幫助我們快速學會HTML架構

<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>
標題A標題B
欄位A1欄位B1
欄位A2欄位B2

練習1: 利用 createElementappendChild 生成前面的表格
表格 = 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. 只能對 documentcreateElement
  2. 也可以對元素 appendChild

應用既有函式和流程控制

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元素屬性

<!-- 這是防疫表單,提醒大家點到 --> <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>
<!-- 這是興大入口 --> <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>

哪來的?



練習2: 選一個前面的表單來生成
防疫表單
表單 = 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")
興大入口
表單 = 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("屬性","屬性值")
例如

元素 = document.createElement("input")
document.body.appendChild(元素)
元素.setAttribute("name","帥哥美女")
元素.setAttribute("value","true")
元素.setAttribute("hidden","")

就生成HTML

<input name="帥哥美女" value="true" hidden>

事件監聽器

點擊 click

HTML嵌入式監聽器

<button onclick="alert('Hello World')"> 按我彈出Hello World </button>

不建議像上面這樣寫,這是在汙染標記語言
onclick 屬性就是監聽器的一種


先生成再監聽

讓你可以在JS繼續操作元素,雖然冗長

元素 = document.createElement("button") document.body.appendChild(元素) 元素.innerHTML = "我是按鈕" 元素.onclick = ev => alert("Hello world")

監聽器可以像上面直接用 . 接在元素後面,也可以

元素 = document.createElement("button") document.body.appendChild(元素) 元素.innerHTML = "我是按鈕" 元素.addEventListener("click", ev => alert("Hello world"))

ev?

就是監聽器捕捉到的事件你可以 console.log(ev) 看看它是什麼東西


練習: 點擊生成按鈕
元素 = document.createElement("button") document.body.appendChild(元素) 元素.innerHTML = "我是按鈕" 元素.onclick = ev => { 元素 = document.createElement("button") document.body.appendChild(元素) 元素.innerHTML = "我是另一個按鈕" }

按鍵 keydown

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

前面的課程已經看膩了吧(?)

//法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


練習: 只使用純 JavaScript,建立5×5的表格,利用按鍵監聽器「移動」紅色欄位
表格元素 = [ ["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"; }

示例


作品展示

Select a repo