1. 什么是DOM: document object model
DOM: 專門操作網頁內容的一套函數和對象
DOM還是一個標准,由W3C制定
為什么:
廣義JS=ECMAScript + DOM + BOM
核心語法 操作網頁內容 訪問瀏覽器軟件
要想操作網頁內容,為頁面添加交互效果,其實只能用DOM函數和對象。
問題: 早起的DOM沒有標准
解決: W3C制定了統一的DOM函數和對象的標准。
幾乎所有瀏覽器100%兼容。
特例: IE8
何時: 只要操作網頁內容,為網頁添加交互行為,只能用DOM
包括: 5件事: 增刪改查 事件綁定
2. DOM樹:
什么是: 在內存中,集中保存一個網頁中所有內容的樹形結構
為什么: 樹形結構是最直觀的保存上下級包含關系的數據結構。而網頁中的HTML標簽,剛好也是父子嵌套的上下級包含關系。所以,網頁中每一項內容,在內存中,都是存在一棵樹形結構上的。
如何:
1. 當瀏覽器讀取到一個.html文件時,會先在內存中創建一個document對象,作為整棵樹的樹根對象
2. 開始掃描.html中每個元素,文本等內容。每掃描到一項內容,就在document下對應位置創建一個節點(node)對象。
3. 查找元素:
1. 不需要查找,就可直接獲得:
document.documentElement <html>
document.head <head>
document.body <body>
2. 按節點間關系查找:
樹上的每個節點都不是孤立存在的。都和上下左右的節點之間有各種各樣的關系,可以互相訪問到。
包括:
節點樹: 包含所有節點內容的完整樹結構
2大類關系:
1. 父子關系:
節點.parentNode 獲得當前節點的父節點
父節點.childNodes 獲得當前父節點下的所有直接子節點的集合。
強調: childNodes返回的是一個類數組對象,今后我都簡稱集合。
父節點.firstChild 獲得當前父節點下的第一個直接子節點。
父節點.lastChild 獲得當前父節點下的最后一個直接子節點。
2. 兄弟關系:
節點.previousSibling 獲得當前節點平級的前一個相鄰的兄弟節點
節點.nextSibling 獲得當前節點平級的下一個相鄰的兄弟節點
問題: 同時包含看不見的換行和空字符,也是節點對象,嚴重干擾查找。
解決: 元素樹
元素樹: 僅包含元素節點的樹結構。
說明: 元素樹不是一棵新樹,而是原來節點樹中添加了僅指向元素節點的新屬性而形成一棵子樹結構。
2大類關系:
1. 父子關系:
元素.parentElement 獲得當前元素的父元素。
說明: 其實也可以用parentNode。
父元素.children 獲得當前父元素下的所有直接子元素的集合。
強調: children返回的是一個類數組對象,今后我都簡稱集合。
父元素.firstElementChild 獲得當前父素下的第一個直接子元素。
父元素.lastElementChild 獲得當前父元素下的最后一個直接子元素。
2. 兄弟關系:
元素.previousElementSibling 獲得當前元素平級的前一個相鄰的兄弟元素
元素.nextElementSibling 獲得當前元素平級的下一個相鄰的兄弟元素
總結: 今后只要按節點間關系查找,都用元素樹的屬性代替節點樹的舊屬性。
何時: 今后只要已經獲得一個節點對象,找周圍附近的節點時。就用節點間關系查找。
鄙視: 定義一個函數,遍歷一個指定的父元素下的所有后代元素:
1. 定義一個函數,僅遍歷直接子元素
2. 如果當前子元素有更下級直接子元素,則對當前子元素繼續調用當前函數,查找子元素的直接子元素
function getChildren(parent){
//arguments.callee->getChildren
//1. 先獲得當前父元素下的所有直接子元素
var children=parent.children;
//遍歷所有直接子元素
for(var child of children){
//輸出當前子元素的標簽名
console.log( child.nodeName )
//元素的標簽名
//2. 如果child有下級直接子元素
if(child.children.length>0){
//就對child繼續調用getChildren
arguments.callee(child)
}
}
}
//查找body下所有后代元素
getChildren(document.body);
3. 按HTML特征查找:
4種:
1. 按id屬性查找
var 元素=document.getElementById("id")
在整個頁面中查找id為指定名稱的一個元素
返回值: 如果找到,返回一個元素對象
如果沒找到,返回null
強調: 只能用document調用。不能再隨意父元素上調用。
2. 按標簽名查找
var 集合=父元素.getElementsByTagName("標簽名")
在指定父元素下查找所有標簽名為指定標簽名的后代元素。
返回值: 如果找到,返回多個元素組成的集合
如果沒找到,返回空集合: [].length=0
強調:
1. 可在任意父元素下查找。通常指定在某個父元素下查找后代,是為了減少查找范圍,提高查找效率。
2. 不止查找直接子元素,而是在所有后代中查找。
比如: nav.getElementsByTagName("li")
<ul id="nav">
<li>
<ul>
<li></li>
<li></li>
<li></li>
</ul>
</li>
<li>
<ul>
<li></li>
<li></li>
<li></li>
</ul>
</li>
</ul>
3. 按class屬性查找
var 集合=父元素.getElementsByClassName("類名")
在指定父元素內,查找class屬性中包含指定類名的所有元素
返回值: 如果找到,返回多個元素組成的集合
如果沒找到,返回空集合: [].length=0
強調:
1. 可限制在任意父元素內查找,減少查找范圍。
2. 不僅查找直接子元素,且在所有后代中查找。
3. 如果一個元素同時被多個class修飾,則使用其中一個class,就可找到該元素。無需所有class都滿足
比如: nav.getElementsByClassName("active")
nav.getElementsByClassName("child")
<ul id="nav">
<li class="item parent">
<ul>
<li class="item child active"></li>
<li class="item child"></li>
<li class="item child"></li>
</ul>
</li>
<li>
<ul>
<li class="item child active"></li>
<li class="item child"></li>
<li class="item child"></li>
</ul>
</li>
</ul>
4. 按name屬性查找
var 集合=document.getElementsByName("name名")
在整個網頁中查找name屬性值為指定name名的元素。
返回值: 如果找到,返回多個元素組成的集合
如果沒找到,返回空集合: [].length=0
強調: 只能用document調用,不能用隨意一個父元素調用。
何時: 在表單中查找表單元素時
問題: 所有返回集合的查找函數,在任何情況下都會返回一個集合。即使只找到一個元素,也放在一個集合中返回。
比如: <form>
<input name="uname">
var 集合=document.getElementsByName("uname")
集合: [ <input> ]
如果想使用集合中返回的這唯一的一個對象,應該?
解決: var 文本框對象=
document.getElementsByName("uname")[0]
其中: [0]表示取出集合中僅有的一個元素對象,單獨使用。
以上四種查找方式,最大的問題是:
一次只能用一個特征作為查找條件。
如果查找條件非常復雜時,代碼會非常繁瑣
解決:
4. 用選擇器當條件查找元素: 2個函數:
1. 只查找一個符合條件的元素:
var 元素=父元素.querySelector("任意復雜的選擇器")
在指定父元素下查找符合選擇器要求的一個元素
返回值: 如果找到,返回一個元素對象
如果沒找到,返回-1
2. 查找多個符合條件的元素:
var 集合=父元素.querySelectorAll("任意復雜的選擇器")
在指定父元素下查找符合選擇器要求的多個元素
返回值: 如果找到,返回多個元素的集合
如果沒找到,返回空集合: [].length=0
強調: 1. 可以以任意父元素調用來限制查找的范圍
2. ()中的選擇器參數,不用每次都寫完整。只要以.前的父元素為起點開始寫就行!
<ul> ul.querySelectorAll("li li")
<li>
<ul>
<li>
<li>
<li>
3. 不僅查找直接子元素,且在所有后代中查找符合條件的。
總結:
1. 不需要查找就可直接獲得:
document.documentElement <html>
document.head <head>
document.body <body>
2. 按節點間關系查找:
1. 父子關系;
元素.parentNode
父元素.children
元素.firstElementChild
元素.lastElementChild
2. 兄弟關系:
元素.previousElementSibling
元素.nextElementSibling
3. 按HTML特征查找:
var 元素=document.getElementById("id")
var 集合=父元素.getElementsByTagName("標簽名")
var 集合=父元素.getElementsByClassName("class名")
var 集合=document.getElementsByName("name名")
4. 按選擇器查找:
var 元素=父元素.querySelector("任意選擇器")
var 集合=父元素.querySelectorAll("任意選擇器")
DOM優化之一:
如果只用一個條件就可以找到想要的元素時
首選使用getElementsByXXX()函數查找——效率高
只有查找條件復雜時,才選擇按選擇器查找——效率低