[基礎課程] JavaScript 教學(二):BOM 與 DOM
本篇介紹 JS 十分重要的兩大模型介紹,如果你希望 JS 能控制並動態調整你的網頁內容。不外乎就是 BOM 與 DOM 模型。BOM 是瀏覽器物件模型,DOM 是文件物件模型,前者是對瀏覽器本身進行操作,而後者是對瀏覽器(可看成容器)內的內容進行操作。
透過下圖可理解整個層級觀念。
- BOM 最根部是指 window,也就是本身整個瀏覽器容器。
- DOM 之最根部的地方,就是 document,就是屬於 BOM 之內。DOM 往下可以延伸出各種 HTML 標籤,一個節點就是一個標籤,往下又可以再延伸出「文本」與「屬性」。
graph TD
subgraph BOM
Window --> document & history & location & navigator & screen
end
document ==> html
subgraph DOM
html --> head & body
head --> title & meta
body --> div & table & form & p
end
style BOM fill:#f9f,stroke:#333,stroke-width:4px
style DOM fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5, 5
此時 JS 可以由 DOM 去存取並改變 HTML 文件之架構、樣式和內容的方法,簡單來說 JS 可以透過 DOM 提供的方式來對 HTML 做存取與操作,以及同時用 BOM 做一些反應事件。BOM/DOM 的最大差別在於:
- BOM: JS 與瀏覽器溝通的窗口,不涉及網頁內容。
語法範例 >>window.alert("hello world");
- DOM: JS 用來控制網頁的節點與內容的標準。
語法範例 >>window.document.write("hello world");
常用的 BOM 操作
由於最上層一定是 window,所以是可以省略不寫 window。有些是屬性=物件{}有些是方法=函式 ()被歸入使用。請參考 MDN 說明 https://developer.mozilla.org/zh-CN/docs/Web/API/Window
console()
指令輸出//請一行行輸入下列確認差異性
console.log("helo world");
console.info("same like log");
console.error("it no work");
console.warn("you have trobule");
ary=['apple','banana','cup'];
console.table(ary);
console.table(history);
console.clear();history()
提供控制可遊覽紀錄的方式history.back(); //回前頁
history.forward(); //下一頁
history.go(1); //用數字+-代表前後跳幾頁screen{}
提供相關螢幕的數據,更多內容請詳 MDN 說明網址screen.width;
screen.availWidth;location{}
控制 URL 的方式,更多內容請詳 MDN 說明網址location.href; //取得目前 URL
location.href="https://www.google.com"; //將目前 URL 指定為某 URL;
location.assign("https://www.google.com"); //指定瀏覽到某 URL;open(),close()
控制新視窗,更多內容請詳 open - MDN 說明網址、close - MDN 說明網址open("https://www.w3schools.com"); //控制打開視窗
var myzone=open("https://www.w3schools.com","","width=200,height=100"); //控制打開視窗
myzone.close();alert(),prompt(),confirm()
alert("hello world"); //提示視窗
var ans=confirm("question"); //提問,回傳布林值
alert(`you select ${ans}`);
var ans=prompt("question","default value"); //提問取得字串並回傳
alert(`you report is ${ans}`);setTimeout(),clearTimeout()
end=5*1000;
function delay(){
console.log("game over");
}
setTimeout(delay,end); //延後執行
// var myvar=setTimeout(delay,end);
// clearTimeout(myvar);setInterval(),clearInterval()
i=0;
function reply(){
console.log(i);
i++;
if(i==5) clearInterval(time); //成真時取消 time 的倒數
}
var time=setInterval(reply,1000); //每 1 秒重複執行此處
課堂作業
建立空白網頁,使用 ifelse, alert, confirm, prompt,設計一個是非題之闖 5 關遊戲。每題都有提示要不要做,猜對繼續闖關,猜錯直接結束遊戲。主體結構如下:
<body> |
示範參考:
常用的 DOM 操作
由於最上層一定是 window,所以可以省略不寫 window。一般是從 document 開始寫,有些是屬性=物件{}有些是方法=函式 ()被歸入使用。請參考 MDN 說明 https://developer.mozilla.org/zh-CN/docs/Web/API/Document
使用 DOM 時,依據物件路徑一個個往內找。通常語法結過如下,
var txt=document.getElementById("demo").innerHTML; //指定為 txt=物件。方法。子屬性 |
document 物件
在 document 物件底下會存放一些子物件可以直接獲取 HTML 文件內的大群組元素可直接找到,或者下節部分透過 get 方式找到指定條件的範圍元素。
document. 子物件 | 描述 |
---|---|
document.head | head 元素,但唯獨屬性不可修改 |
document.body | body 元素,操作例如document.body.style.backgroundColor="red"; |
document.forms | 文件內的全部表單元素之通用集合 |
document.links | 文件內的全部具備 href 之元素之通用集合 |
document.images | 文件內的全部 img 元素之通用集合 |
document.scripts | 文件內的全部 script 元素之通用集合 |
如通用集合內的元素持有 id 或 name 可更快指向找到,例如:
<img src="https://fakeimg.pl/200x200" name="aa"> |
節點存取
document. 方法 | 描述 |
---|---|
getElementById(id) | 以 id 找,唯一值 |
getElementsByClassName(name) | 以 class 找(多筆),回傳 array |
getElementsByTagName(name) | 以標籤找(多筆),回傳 array |
getElementsByName(name) | 以表單屬性 name 去找(多筆),回傳 array |
素材準備:準備代碼以方便下階段的教學練習
<html> |
示範如何透過 ById 去讀取修改內容
<script>
var obj = document.getElementById("demo");
alert(obj.innerHTML);
obj.innerHTML = "<li>AAA</li><li>BBB</li>"; //抓 HTML 修改
obj.textContent = "<li>AAA</li><li>BBB</li>"; //抓出文字,遇 HTML 自換符號
//obj.innerText 同上效果,屬於舊 IE8 語法但 Firefox 不支援
</script>示範如何透過 ByClass 去得到多組物件並讀取修改內容
<script>
var food=document.getElementsByClassName("list");
console.log(food);
alert(food[0].textContent);
food[0].innerHTML="<b>AAA</b>";
</script>示範如何透過標籤去得到多組物件並讀取修改內容
<script>
var food = document.getElementsByTagName("li");
console.log(food);
alert(food[1].textContent);
food[1].innerHTML = "<b>BBB</b>";
</script>
Event 事件
Event 的事件非常多,是指當偵測某物件的狀態成立時觸發執行{}某 JS。有分為滑鼠、鍵盤、觸碰裝置、遊覽器、元素等各種事件,通常會搭配自訂函式形成一個互動反應。以下只列舉幾個簡單的事件
更多 Event 請參考 W3Schools 說明網址
mouse event
document. 方法 | 描述 |
---|---|
onclick,dblclick,onmousedown,onmouseup | 點選,雙點,滑鼠按下,彈起 |
oncontextmenu | 滑鼠右鍵 |
onmouseover,onmouseout | 滑鼠移入,移出 |
onchange | 常用於表單,當內容有變化時 |
onfocus | 獲得焦點 |
onblur | 失去焦點 |
onsubmit | 表單提交 |
onreset | 表單重置 |
focus/blur有雷同的用法為focusin/focusout,兩者差異後者支援冒泡事件但瀏覽器並非都支援
touch event
document. 方法 | 描述 |
---|---|
ontouchcancel | 觸碰取消 |
ontouchend | 觸碰離開 |
ontouchmove | 觸碰按壓 |
ontouchstart | 觸碰按下 |
kerboard event
document. 方法 | 描述 |
---|---|
onkeyup | 按鈕彈起 |
onkeydown | 按鈕按下 |
onkeypress | 按鈕按下並起來 |
browser event
window. 方法 | 描述 |
---|---|
onload | 元素載入後時 |
onresize | 視窗改變尺寸時 |
這裡的寫法可使用在 HTML 屬性或透過 JS 對元素物件綁定,後面會講到監聽事件之另一種方法
透過 HTML 屬性觸發
素材準備:準備代碼以方便下階段的教學練習
<html> |
請跟著做,滑鼠點擊任何地方理解 JS 動作
function showalert(msg) { |
透過 JS 監聽行為觸發
使用 addEventListener() 與 removeEventListener() 做可維護管理的事件用函式,直接指定事件與對象。
素材準備:準備代碼以方便下階段的教學練習
<body> |
/*一開始 HTML#ock 沒有寫事件,之後透過 addEventListener(什麼動作,執行什麼函式)來添加*/ |
節點的屬性讀寫
element. 方法 | 描述 |
---|---|
innerHTML | HTML Cdoe |
textContent | text string |
attribute.??? - name,value,… |
該節點的屬性 (ary), 除了可讀寫現有名稱或值 |
setAttribute,removeAttribute | 屬性設定,常用於增刪 class 或 id |
style.??? | 該節點的行內樣式,每一個 (???) 樣式都算一個屬性,如果要移除需指定此屬性為 null |
節點調整
document. 方法 | 描述 |
---|---|
createElement() | 建立節點 |
removeChild() | 删除子節點 |
appendChild() | 增加子節點 |
replaceChild() | 替換子節點 |
write() | 直接寫入 |
<body> |
課堂練習
- 建立一個 div 預設值為
width: 100px; height: 100px; background-color:red;
- 理解將 div 設計為正方形、圓形、三角形之 CSS 屬性方式,參考這裡。
- 提供事件按鈕與輸入框,能對 div 做 CSS 變化
- button: 正方形
- button: 圓形
- button: 三角形
- input:text(#color code)>變化背景色
<body> |
課堂作業
設計 div 長寬隨意,每次開啟網頁時 BGcolor 隨機色(具提示),提供下列按鈕可立即更改顏色。
基本款
- R 紐,跳出視窗提示輸入數字範圍 0~255,非範圍內重新再問
- G 紐,跳出視窗提示輸入數字範圍 0~255,非範圍內重新再問
- B 紐,跳出視窗提示輸入數字範圍 0~255,非範圍內重新再問
完成再挑戰
- +紐,對 RGB 各色值+1,合理範圍內
- -紐,對 RGB 各色值-1,合理範圍內
- input:range 拖曳 bar 代表 (R 色) 0~255 立即有效果
- input:range 拖曳 bar 代表 (G 色) 0~255 立即有效果
- input:range 拖曳 bar 代表 (B 色) 0~255 立即有效果
- ? 紐,對 RGB 重新再隨機色
示意圖如下: