JavaScript CSS3

Javascript 動態網頁程式設計 - 上課教材

動畫互動網頁程式設計 > 課程內容 > 第 02 章 - DOM 基礎與取得/修改網頁上的元件

第 02 章 - DOM 基礎與取得/修改網頁上的元件

上次更新日期 2020/09/11

JavaScript 有很多種方式取得網頁上的元件,也有很多種參數來修改網頁上的元件,但無論如何,都得要先知道一點 DOM ( Document Object Model ) 模型, 這樣才有辦法理解 javascript 與元件之間的關係。

學習目標:

  1. 初步了解 DOM 的結構
  2. 學會 document.getElementByID, document.getElementsByName, document.getElementsByTagName 的用法
  3. 使用 function 功能

2.1: 簡易的 DOM 介紹

在開始 DOM 的介紹之前,我們先來聊聊一般來說,瀏覽器從伺服器或本機的檔案當中取得網頁資料後,是如何進行呈現的呢? 基本上的流程大致上是這樣的:

  1. 瀏覽器載入 html5 的網頁,同時載入了 CSS, Java script 與影音資料等多媒體項目;
  2. 瀏覽器分析了網頁內容,依據各個標記的父元素與子元素的內容,建立了 DOM 文件模型;
  3. 載入的 java script 開始根據 DOM 模型,在特定的元素之間與使用者互動;
  4. 如果設定得宜,更多的 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";
例題 2-2-1:使用 這個檔案 的內容,並依據底下的方式設計網頁:
  1. 建立 unit02-2-1.php,並在 index.php 裡面加上相關的超連結,target 指向 js 視窗。
  2. 將上述的檔案內容加入此網頁中,先查看一下網頁的格式,了解一下幾個重點:
    • 在 Tag 內的屬性中, id 應該要是獨一無二的存在為主
    • 在 Tag 內的屬性中, name 可以出現在很多地方
    • 有時候可以直接抓取 Tag 來應用。
  3. 使用『onclick="document.getElementById('mycode').style.border='1px solid gray'"』之類的方式,增加框線
  4. 使用『document.getElementsByName('mytxt1')[0].style.color='green'』之類的方式,修改字體,注意那個 [0] 的項目, 因為 Name 取得的會是陣列,所以有多個陣列時,可以使用分號 (;) 持續撰寫 javascript
  5. 使用『document.getElementsByTagName('h1')[0].style.color='blue'』修改 HTML 標籤的內容來修改 style 資訊。
onclick 結果

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 的標籤內。

例題 2-3-1:嘗試使用 function 處理
  1. 將 unit02-2-1.php,另存新檔為 unit02-3-1.php,並在 index.php 裡面加上相關的超連結,target 指向 js 視窗。
  2. 在第一個按鈕定義 mycodef() 函數,且 mycodef 函數會進行:
    • 指定一個變數名稱為 mycode,這個變數名稱會取得 mycode 這個 id 的元素資訊
    • 變更 mycode 的框線,例如 1px solid gray
    • 變更 mycode 的內部留白,例如 10px
    • 變更 mycode 的背景顏色,例如 lightyellow
    • 相關的 javascript 適用的 CSS style 屬性與值,請參考文末的 W3C 網站資料。
  3. 在第二個按鈕處定義 mytxt1f() 函數,且 mytxt1f 函數會進行:
    • 指定一個變數名稱為 mytxt1,這個變數名稱會取得 mytxt1 這個 name 的元素資訊,取得的資料為陣列喔!
    • 變更 mytxt1 第 0 個陣列的顏色是灰色
    • 變更 mytxt1 第 1 個陣列的顏色是灰色
  4. 在第三個按鈕處定義 mytxt2f() 函數,且 mytxt2f 函數會進行:
    • 指定一個變數名稱為 mytxt2,這個變數名稱會取得 mytxt2 這個 name 的元素資訊,取得的資料為陣列喔!
    • 變更 mytxt2 第 0 個陣列的顏色是白色,且背景色會是藍色
    • 變更 mytxt2 第 1 個陣列的顏色是白色,且背景色會是藍色
  5. 在第四個按鈕處定義 myh1f() 函數,且 myh1f 函數會進行:
    • 指定一個變數名稱為 myh1,這個變數名稱會取得 h1 這個標籤 (tag) 的元素資訊,取得的資料為陣列喔!
    • 變更 myh1 第 0 個陣列的顏色是綠色,且背景色會是淺黃色
onclick 結果

透過取得網頁上面的元素,並且透過變數來讓取得的資料變成一個簡單的變數,方便進一步處理,這就可以對你的網頁進行大幅度的變更, 也讓你的使用者可以透過點擊或者其他相關的輸入,來跟你的網頁互動了。

2.4: 使用 .innerHTML 與 .outerHTML 功能

其實 javascript 在網頁上可以做非常非常多的事情,除了取得網頁元件來進行修改其 CSS 屬性之外,也可以透過 .innerHTML 或 .outerHTML 來修改元件內部資料,或者是整個元件 (含 tag 本身) 的資料喔!這個 .innerHTML 或 .outerHTML 也是得要搭配 getElement(s)By{Id,Name,TagName} 的設計。

例題 2-4-1:使用 innerHTML 功能,修改元件內部的資料
  1. 將 unit02-3-1.php,另存新檔為 unit02-4-1.php,並在 index.php 裡面加上相關的超連結,target 指向 js 視窗。
  2. 這個檔案的內容 貼到網頁上
  3. 建立需要的腳本:
    • 建立名為 mydate 的變數,變數為取得 mydate 這個 id 的元件
    • 透過 mydate 指定內容變為使用 Date() 這個 javascript 內建函數,取得瀏覽器端的時間
onclick 結果

如上所示,透過 .innerHTML 就可以修改元件內的資料。不過,如果你還想要修改標記本身,那就得要透過 .outerHTML 的修訂了。

例題 2-4-2:使用 outerHTML 功能,修改元件內部的資料
  1. 將 unit02-4-1.php,另存新檔為 unit02-4-2.php,並在 index.php 裡面加上相關的超連結,target 指向 js 視窗。
  2. 修改腳本:
    • 透過 outerHTML 的功能,將 p 改變成為 pre 的標記
    • 要注意,變更標記的時候,需要連同內容一起加入,所以,可能需要以 AAA + BBB + CCC 的方式累加, 亦即 javascript 內,是以加號 (+) 進行字串的累加。
onclick 結果

使用 outerHTML 連同標記本身都可以修改!以上面的範例來說,可以修改 p 變成 pre!方便未來將網頁上面的元件特性進行修改。

2.5: 課後作業

一開始的網頁如 這個網頁 的內容一般,請將該內容轉存成為 unit02-5-1.php 的檔案內容。 然後套用底下的圖檔: 剪刀, 石頭, 當使用者點擊不同的按鈕時,就會出現相對的圖示到方塊當中。同時,在網頁當中的 p 標記,應該改換成為 h1 標記, 並且將出的猜拳名稱填寫到該標記當中 (注意,該標記中的 id 也得要繼續存在喔!)。設計起來,會有點像這樣:

作業簡單示意圖

2.6:參考資料