只在此山中,雲深不知處


聽首歌



© 2018 by Shawn Huang
Last Updated: 2018.5.27

DOM

DOM是Document Object Model的縮寫,每次載入網頁時,瀏覽器便會建立DOM,DOM將網頁內的物件以樹狀排列。例如head跟body是html的children,title又是head的child,而html為整個樹的root。這個結構可以協助我們取得網頁內的物件,進而針對物件進行新增修改刪除等操作。
HTML DOM document物件是網頁中所有物件的擁有者,所以document便是表示整個網頁,要取得網頁中的物件,永遠都要使用document關鍵字開頭。document擁有以下方法來讓我們取得、改變與增刪物件。
取得物件element後,可以使用屬性或方法來取得或改變屬性的值。

Finding elements


根據上述,舉例說明如何取得網頁物件。 >>
先設計以下html。

加上函數。
按以下按鈕看結果。
Say hello inside h5


再試試看使用getElementsByTagName。 >>

加上函數。

第一個p

第二個p

第三個p


顯然使用byTagName會得到所有相同Tag的物件(所以是Elements),而且這些物件會放在類似array的結構內(稱為collection)。 此外,第三個p顯然在css有個名為p11的class來改變其背景顏色。

接下來再試試看使用getElementsByClassName。 >>

加上函數。
h6

p

section

顯然跟getElementsByTagName類似,只是這次抓取所有相同class name的物件。
另一個類似的方式為使用querySelectorAll()方法,此方法可以抓取相同CSS selector的元件。 >>

加上函數。
h6

p

section

記得argument是CSS selector,所以要用.js11_4。
上述兩方式效果類似,一個傳回collection,一個傳回nodelist,差別是collection是elements的集合,而nodelist是document nodes的集合。 文件中所有東西都是node,而element是一種特殊的node。只有nodelist物件可以包含屬性node與文字node。 我們可以根據名稱,id,或index number取得collection內的元件,但是只能使用index number來取得nodelist內的元件。

Event Linstener


可以使用addEventListener方法直接將event跟函數連結在物件上,效果跟上述的按鈕相同。 >>

加上函數。

跟之前使用onclick類似,有一點要注意的是addEventListener的script要寫在元件(button)之後(如上),不然會因傳回空(null)而出錯。

跟之前一樣的,同一個element可以同時有超過一個event。 >>

Event Bubbling & Event Capturing


當一個element位於另一個element之內成巢狀排列(Nested)時,若是兩者的event同時被觸發,哪一個element的event要先執行? >>

加上函數。

在addEventListener參數加上false表示是Bubbling,true表示Capturing。在之下的圖形中按下bubbling,會發現內層的element之event先執行,Capturing則外層先執行。 可知Bubbling表示由內而外,Capturing表示由外而內。

Bubbling

Capturing

removeEventListener()


Event handler也可以被移除,使用removeEventListener()方法。 >>

加上函數。

按這裡移除listener

顯示滑鼠位置

Navigating Between Nodes


我們已經了解整個在HTML document中任何東西都是一個node,例如整個document是一個document node, 每一個HTML element都是一個element node,文字是一個文字node,每一個屬性是屬性node,連註解也是一個註解node。 而所有這些形成一個樹狀排列。通常html是root,head, body是他的child,head跟body彼此是siblings。因此我們 可以利用之前列出的許多方法找到某一個node的對應關係物件,例如其child或是parent。 >>
設計一個按鈕並利用之前用來展示bubbling&capturing的物件。
加上函數。

按下按鈕後可以發現兩者皆得到相同的文字,對於p來說,其內的文字是其child node,但是text並不是一個element, 所以使用nodeValue取得其內的值。而p是div的first element child,不是第一個node child,所以使用firstElementChild取得p, 此時使用innerHTML來得到element內的值。此外,顯然children取得所有的child elements,而childNodes取得所有的child nodes。 要注意的是對於element來說,其nodeValue是undefined。

Adding & Deleting


可以使用前述的方法來增減文件。>>

加上函數。

此時按下Button A可看見變化。 再加上Button B的函數。

使用setAttribute()可得到與setAttributeNode()一樣的效果。 再加上Button C的函數。

可以看到加上第一個p的sibling,接著再加上Button D的函數。

可以看到移除了最後一個p。