第 02 章 - DOM 基礎與取得/修改網頁上的元件
上次更新日期 2020/09/11
JavaScript 有很多種方式取得網頁上的元件,也有很多種參數來修改網頁上的元件,但無論如何,都得要先知道一點 DOM ( Document Object Model ) 模型, 這樣才有辦法理解 javascript 與元件之間的關係。
學習目標:
- 初步了解 DOM 的結構
- 學會 document.getElementByID, document.getElementsByName, document.getElementsByTagName 的用法
- 使用 function 功能
- 2.1: 簡易的 DOM 介紹
- 2.2: 取得網頁上元素資料的手段
- 2.3: 使用 function 功能
- 2.4: 使用 .innerHTML 與 .outerHTML 功能
- 2.5: 課後作業
- 2.6: 參考資料
2.1: 簡易的 DOM 介紹
在開始 DOM 的介紹之前,我們先來聊聊一般來說,瀏覽器從伺服器或本機的檔案當中取得網頁資料後,是如何進行呈現的呢? 基本上的流程大致上是這樣的:
- 瀏覽器載入 html5 的網頁,同時載入了 CSS, Java script 與影音資料等多媒體項目;
- 瀏覽器分析了網頁內容,依據各個標記的父元素與子元素的內容,建立了 DOM 文件模型;
- 載入的 java script 開始根據 DOM 模型,在特定的元素之間與使用者互動;
- 如果設定得宜,更多的 java script APIs 就開始一起應用了(例如影音多媒體)
基本上,一般網頁都是將全部的資料都下載完畢後,這才開始進行後續資料的運作。而第 2 步驟裡面的說明是怎麼回事呢?從前面幾章的資料來看, 我們知道整個網頁的 HTML 文件都是從 HTML 開始的,然後 HTML 裡面主要有 head 以及 body 兩個標籤,而 body 內部的標籤就有夠多的了! 且元素之間有相關性,亦即有所謂的父元素與子元素,那麼這些元素之間就有相關性 (有父有子),將這些資料依據父子關係串在一起, 這就是最單純的 DOM 樹狀模式模型了。從 wiki 的圖示當中,我們大概可以看出個大概:
在這個模型中,最頂層的資料,就是整份文件 (document),請將這個英文背下來,未來會經常用到它。
除了這個元素之間的相依性之外,每一個元素都可有擁有許多的屬性,然後這些屬性除了可以讓 CSS 靜態的改變之外,也可以透過 javascript 的程式與互動功能,讓這些元素的屬性被動態修改,因此就會有許多的變化產生。那麼 javascript 可以做哪些元素的屬性處理呢? 基本上, javascript 可以根據 DOM 進行如下的行為:
- javascript 可以新增、移除 HTML 網頁裡面的所有元素
- javascript 可以刪除、修改、新增所有元素的相關屬性資料
- javascript 可以變更元素的 CSS 風格樣式
- javascript 可以與已經存在的各個元素進行互動,包括滑鼠與鍵盤的事件觸發等
2.2: 取得網頁上元素資料的手段
根據 DOM 的模型,我們可以透過 javascript 的幾個方式來取得網頁上面的元件!同時,根據取得的元素的方法不同,而有不一樣的資料類型喔! 舉例來說,使用 id (不是 class 喔!) 進行資料的取得將是『唯一』的,因此該資料的取得就會是單一的變數。而使用 name 或 標記 (tag) 來取得元素的話,因為網頁上很多元素會定義相同的名稱 (例如表單的單選資料) 或相同的標記 (例如清單的 li 或圖片的 img),因此,這些方式取得的變數,就會是『陣列』的形式喔!
至於 javascript 取得網頁上面的元件方式中,必須要從『整個網頁 (document)』的角度去思考,因此,取得元素的控制權, 就會有底下的幾種語法:
- document.getElementById("id_name"):透過 id 名稱取得控制權,單一變數
- document.getElementsByName("name_name"):透過 name 取得控制權,陣列變數
- document.getElementsByTagName("tag_name"):透過標記的名稱取得控制權,陣列變數
要注意喔,javascript 與 HTML 不一樣,javascript 的語法是有大小寫分別的,所以,上面的 3 個語法中,Element 與 By 與 Id, Name, TagName 的大小寫部份要注意~另外,除了第一個是單一變數,所以使用 Element 之外,底下兩個是陣列變數,所以是複數的 Elements 喔! 尾巴多了個 s 啦!
- 屬性參數的取得與變更
javascript 要處理取得的元素的控制權後,想要修改該元素的任何資料,都是使用小數點加上屬性的方式來處理的。 舉例來說,假設有個圖片的 HTML 碼寫這樣:
<img id="img1" src="dir1/img1.ipg" alt="check" />
那麼我們想要控制 img 的 src 時,基本上是這樣處理的:
document.getElementById("img1").src="newfilename.jpg";
看到了嘛?透過 getElementById 取得了 img1 的這個元素之後,將後續檔名的 src 修改掉了!就這麼簡單! 如果要更改 style 呢?那就變成這樣:
document.getElementById("img1").style.border="1px solid grey";
- 建立 unit02-2-1.php,並在 index.php 裡面加上相關的超連結,target 指向 js 視窗。
- 將上述的檔案內容加入此網頁中,先查看一下網頁的格式,了解一下幾個重點:
- 在 Tag 內的屬性中, id 應該要是獨一無二的存在為主
- 在 Tag 內的屬性中, name 可以出現在很多地方
- 有時候可以直接抓取 Tag 來應用。
- 使用『onclick="document.getElementById('mycode').style.border='1px solid gray'"』之類的方式,增加框線
- 使用『document.getElementsByName('mytxt1')[0].style.color='green'』之類的方式,修改字體,注意那個 [0] 的項目, 因為 Name 取得的會是陣列,所以有多個陣列時,可以使用分號 (;) 持續撰寫 javascript
- 使用『document.getElementsByTagName('h1')[0].style.color='blue'』修改 HTML 標籤的內容來修改 style 資訊。
2.3: 使用 function 功能
不過,從上面的作法來看,一切的設計都是在 onclick 裡面處理,那麼整個動作似乎有點麻煩。又例如 getElementsByName 的項目, 因為取得的資料是陣列,因此若有多個項目,就得要在 onclick 裡面增加好多條設計,這樣實在有點麻煩。 此時,透過 function 的方式,就可以將這個動作簡化了。
- 透過 function 變動網頁元件的方式
使用 function 的方式有點像底下這樣:
<button type="button" onclick="myfunction()"> Click me to display Date and Time. </button> <script> function myfunction() { document.getElementById('mycode').style.border = '1px solid gray'; .... } </script> <p id="demo"></p>
也就是說,你可以加入許多的程式碼在一個 function 裡面,然後透過 onclick 的功能去呼叫出來執行, 這樣當然直觀許多!而不是讓一堆程式碼亂亂的卡在 HTML 的標籤內。
- 將 unit02-2-1.php,另存新檔為 unit02-3-1.php,並在 index.php 裡面加上相關的超連結,target 指向 js 視窗。
- 在第一個按鈕定義 mycodef() 函數,且 mycodef 函數會進行:
- 指定一個變數名稱為 mycode,這個變數名稱會取得 mycode 這個 id 的元素資訊
- 變更 mycode 的框線,例如 1px solid gray
- 變更 mycode 的內部留白,例如 10px
- 變更 mycode 的背景顏色,例如 lightyellow
- 相關的 javascript 適用的 CSS style 屬性與值,請參考文末的 W3C 網站資料。
- 在第二個按鈕處定義 mytxt1f() 函數,且 mytxt1f 函數會進行:
- 指定一個變數名稱為 mytxt1,這個變數名稱會取得 mytxt1 這個 name 的元素資訊,取得的資料為陣列喔!
- 變更 mytxt1 第 0 個陣列的顏色是灰色
- 變更 mytxt1 第 1 個陣列的顏色是灰色
- 在第三個按鈕處定義 mytxt2f() 函數,且 mytxt2f 函數會進行:
- 指定一個變數名稱為 mytxt2,這個變數名稱會取得 mytxt2 這個 name 的元素資訊,取得的資料為陣列喔!
- 變更 mytxt2 第 0 個陣列的顏色是白色,且背景色會是藍色
- 變更 mytxt2 第 1 個陣列的顏色是白色,且背景色會是藍色
- 在第四個按鈕處定義 myh1f() 函數,且 myh1f 函數會進行:
- 指定一個變數名稱為 myh1,這個變數名稱會取得 h1 這個標籤 (tag) 的元素資訊,取得的資料為陣列喔!
- 變更 myh1 第 0 個陣列的顏色是綠色,且背景色會是淺黃色
透過取得網頁上面的元素,並且透過變數來讓取得的資料變成一個簡單的變數,方便進一步處理,這就可以對你的網頁進行大幅度的變更, 也讓你的使用者可以透過點擊或者其他相關的輸入,來跟你的網頁互動了。
2.4: 使用 .innerHTML 與 .outerHTML 功能
其實 javascript 在網頁上可以做非常非常多的事情,除了取得網頁元件來進行修改其 CSS 屬性之外,也可以透過 .innerHTML 或 .outerHTML 來修改元件內部資料,或者是整個元件 (含 tag 本身) 的資料喔!這個 .innerHTML 或 .outerHTML 也是得要搭配 getElement(s)By{Id,Name,TagName} 的設計。
- 將 unit02-3-1.php,另存新檔為 unit02-4-1.php,並在 index.php 裡面加上相關的超連結,target 指向 js 視窗。
- 將 這個檔案的內容 貼到網頁上
- 建立需要的腳本:
- 建立名為 mydate 的變數,變數為取得 mydate 這個 id 的元件
- 透過 mydate 指定內容變為使用 Date() 這個 javascript 內建函數,取得瀏覽器端的時間
如上所示,透過 .innerHTML 就可以修改元件內的資料。不過,如果你還想要修改標記本身,那就得要透過 .outerHTML 的修訂了。
- 將 unit02-4-1.php,另存新檔為 unit02-4-2.php,並在 index.php 裡面加上相關的超連結,target 指向 js 視窗。
- 修改腳本:
- 透過 outerHTML 的功能,將 p 改變成為 pre 的標記
- 要注意,變更標記的時候,需要連同內容一起加入,所以,可能需要以 AAA + BBB + CCC 的方式累加, 亦即 javascript 內,是以加號 (+) 進行字串的累加。
使用 outerHTML 連同標記本身都可以修改!以上面的範例來說,可以修改 p 變成 pre!方便未來將網頁上面的元件特性進行修改。
2.5: 課後作業
一開始的網頁如 這個網頁 的內容一般,請將該內容轉存成為 unit02-5-1.php 的檔案內容。 然後套用底下的圖檔: 剪刀, 石頭, 布 當使用者點擊不同的按鈕時,就會出現相對的圖示到方塊當中。同時,在網頁當中的 p 標記,應該改換成為 h1 標記, 並且將出的猜拳名稱填寫到該標記當中 (注意,該標記中的 id 也得要繼續存在喔!)。設計起來,會有點像這樣:
2.6:參考資料
- Javascript 可以使用的 CSS style 設定參數:https://www.w3schools.com/jsref/dom_obj_style.asp