DOM節點的選取
DOM除了有「HTML元素節點」外,還有「文字節點」、「註解節點」…等等。
選取DOM的節點方法如下:
ex:
1 | ---html文件--- |
DOM節點間的查找遍歷(Traversing)
DOM節點與節點之間,大致分成以下兩種:
父子關係: 該節點的上一層node是「父節點」,該節點的下一層節點是「子節點」。
兄弟關係: 有同一個「父節點」的節點,彼此之間就稱為「兄弟節點」。
另外,有以下幾種方法可以取得子節點、父節點、兄弟節點的方法:Node.childNodes
: 會回傳的NodeList,並用這個回傳的NodeList來遍歷每個子節點Node.firstChild
: 取得Node節點的第一個子節點Node.lastNodes
: 取得Node節點的最後一個子節點Node.parentNode
: 取得父元素,回傳值有可能是一個元素節點、根節點 或 DocumentFragmentNode.previousSibling
: 取得同一層之間的「前一個」節點,若該節點已經是 第一個節點 時,回傳null
Node.nextSibling
: 取得同一層之間的「下一個」節點,若該節點已經是 最後一個節點 時,回傳null
document.getElementsBy*** 與 document.querySelector/document.querySelectorAll 的差異
document.getElementById
以及document.querySelector
只會取得一個元素/節點,故不會有index和length屬性。document.getElementsBy***
與document.querySelector/document.querySelectorAll
分別會回傳
「HTML Collection」與「NodeList」。
HTML Collection: 只收集HTML元素節點。
NodeList除了HTML節點,也會回傳文字節點 和 屬性節點等。document.querySelector/document.querySelectorAll 取得的NodeList是靜態的
即透過document.querySelector/document.querySelectorAll
取得的NodeList,不會動態地隨著網頁元素的增減,跟著一起變動。
ex:
1 | ---HTML文件--- |
DOM Node 的建立、刪除、修改與外觀
DOM 節點的新增
document.createElement(tagName)
ex:經過1
let newDiv = document.createElement('div');
document.createElement(tagName)
新增的元素,我們還無法在網頁上看到它們,
需要透過appendChild()
、inserBefore()
、replaceChild()
等方法,將這些新元素加入指定的位置,
才能在網頁上看到它們。
另外,我們也可以直接對這些新增元素新增屬性
ex:
1 | newDiv.id = 'newDiv'; // 新增id屬性 |
document.createTextNode()
a. 用來建立文字節點
b. 在新增的TextNode被加入某個節點前,是無法看不到它的
ex:1
2
3let newDiv = document.createElement('div');
let newTextNode = document.createTextNode('Hello World');
newDiv.appendChild(newTextNode); // 將newTextNode塞入newDiv裡面document.createDocumentFragment()
a. 它是一種沒有父層節點的「最小化文件」
b. 如同標準文件一般的方式來保存「片段的文件結構」
c. DocumentFragment不是真實的DOM結構,
所以,DocumentFragment變動並不會影響目前網頁文件,也不會導致回流(reflow)或引起
任何影響效能的狀況。
故當要大量操作DOM的元素時,用DocumentFragment的效能會比直接操作DOM還要好。document.write()
可用write()
將某內容寫入網頁中,其內容可以不只是單純的字串,也可以是HTML的標籤。
ex:
1 | document.write("<h1>hello world</h1>"); |
甚至要新增<script>
標籤,並指定外部js資源也是可以。
ex:
1 | document.write("<script type=\"text\javascript\" src=\"file.js\">" + "<\/script>"); |
write()
裡面的內容,會完全覆蓋目前網頁的內容。
DOM節點的修改與刪除
書中介紹了一下幾種方法
NODE.appendChild(childNode)
此方法會將childNode插入父容器節點末端NODE.insertBefore(newNode, refNode)
將newNode節點插在redNode前面NODE.replaceChild(newChildNode, oldChildNode)
將oldChildNode換成指定的newChildNodeNODE.removeChild(childNode)
將指定的子節點childNode刪除
修改元素的style屬性
透過JS來修改元素的style屬性,就是屬於修改「行內樣式」的類型。
ex:
1 | ---HTML文件--- |
a. 以上這種寫法的優先權會高過很多其他的寫法(!important
除外)。
b. 另外,很多css屬性名中有破折號-,故你用上面這種JS修改的寫法得改成”駝峰式”的寫法
ex:
1 | box.style.font-size = '10px'; // 不允許!!! |
修改元素的class屬性
透過className
來操作網頁標籤內的class屬性
ex:
1 | ---html文件--- |
用以上這種寫法的話,會有一種問題,就是不會保留原本的className。
所以,DOM api提供了classList
屬性來取代className
。
classList
是一個唯讀的屬性。
即我們無法透過這個屬性直接更改class的屬性。
但能透過classList.add()
和classList.remove()
來修改它。
ex:
1 | ---html文件--- |
利用JavaScript直接寫入CSS樣式
way1. 在<head>
利用document.write
寫入CSS
ex:
1 | document.write('<link rel="stylesheet" href="xxx.css"/>'); |
way2. 利用document.createElement
來新增link標籤
ex:
1 | let head = document.querySelector('head'); |
以上這種方法,可以在滿足某個條件下,才寫入特定的CSS樣式