Document 對象提供了屬性和方法實現定位頁面元素功能,這也是 DOM 的標準規范中 Document 對象的主要應用之一。
## 定位頁面元素方法
目前 Document 對象提供實現定位頁面元素的方法具有如下幾種:
- getElementById()方法:通過頁面元素的 id 屬性值定位元素。
- getElementsByName()方法:通過頁面元素的 name 屬性值定位元素。
- getElementsByTagName()方法:通過頁面元素的元素名定位元素。
- getElementsByClassName()方法:通過頁面元素的 class 屬性值定位元素。
- querySelector()方法:通過 CSS 選擇器定位第一個匹配的元素。
- querySelectorAll()方法:通過 CSS 選擇器定位所有匹配的元素。
接下來,我們就一一進行學習。
## 通過元素的 ID 屬性值定位元素
HTML 頁面元素的 id 屬性的特點是唯一、不可重復的,所以通過這種方式定位的 HTML 頁面元素也是唯一的。
其語法格式如下:
```javascript
element = document.getElementById(id);
```
在上述語法中,id 是參數,表示所要定位元素的 id 屬性值,是一個大小寫敏感的字符串。element 是返回值,表示定位的元素,是一個 Element 對象。
> **值得注意的是:** 如果 HTML 頁面中不存在具有該 id 屬性值的元素,則返回 null。
下面是使用 getElementById() 方法的示例代碼:
```javascript
var btn = document.getElementById('btn');
// 獲取定位元素的 class 屬性值
var className = btn.className;
// 添加 animate 動畫樣式
className += ' animate';
// 將新的 class 屬性值設置
btn.className = className;
```
上述代碼通過 getElementById() 方法定位 HTML 頁面中 id 屬性值為 btn 的元素,并為其元素的 class 屬性添加 animate 樣式。
## 通過元素的 name 屬性值定位元素
其語法格式如下:
```javascript
elements = document.getElementsByName(name);
```
在上述語法中,name 是參數,表示所要定位元素的 name 屬性值,是一個大小寫敏感的字符串。elements 是返回值,表示定位元素的集合,是一個 NodeList 集合。
下面是使用 getElementsByName() 方法的示例代碼:
```javascript
var elems = document.getElementsByName('btn');
// 循環遍歷所有元素
for (var i=0; i<elems.length; i++) {
var elem = elems[i];
var className = elem.className;
className += ' animate';
elem.className = className;
}
```
上述代碼通過 getElementsByName() 方法定位 HTML 頁面中 name 屬性值為 btn 的元素,并遍歷所有得到的元素,為其元素的 class 屬性添加 animate 樣式。
## 通過元素的元素名定位元素
其語法格式如下:
```javascript
elements = document.getElementsByTagName(name);
```
在上述語法中,name 是參數,表示所要定位元素的元素名,符號”*”表示所有元素。elements 是返回值,表示定位元素的集合,是一個 NodeList 集合。
下面是使用 getElementsByTagName() 方法的示例代碼:
```javascript
var elems = document.getElementsByTagName('button');
// 循環遍歷所有元素
for (var i=0; i<elems.length; i++) {
var elem = elems[i];
var className = elem.className;
className += ' animate';
elem.className = className;
}
```
上述代碼通過 getElementsByTagName() 方法定位 HTML 頁面中元素名為 button 的元素,并遍歷所有得到的元素,為其元素的 class 屬性添加 animate 樣式。
## 通過元素的 class 屬性值定位元素
其語法格式如下:
```javascript
elements = document.getElementsByClassName(names);
```
在上述語法中,names 是參數,表示所要定位元素的 class 屬性值列表,class 名稱通過空格分隔。
> **值得注意的是:** names 參數可以是一個樣式屬性名稱,也可以是多個樣式屬性名稱。
elements 是返回值,表示定位元素的集合,是一個 NodeList 集合。
下面是使用 getElementsByClassName() 方法的示例代碼:
```javascript
var elems = document.getElementsByClassName('btn');
// 循環遍歷所有元素
for (var i=0; i<elems.length; i++) {
var elem = elems[i];
var className = elem.className;
className += ' animate';
elem.className = className;
}
```
上述代碼通過 getElementsByClassName() 方法定位 HTML 頁面中 class 屬性值為 btn 的元素,并遍歷所有得到的元素,為其元素的 class 屬性添加 animate 樣式。
#### 兼容 IE 8 及之前版本的瀏覽器
getElementsByClassName() 方法只支持 IE 9 版本及之后版本的瀏覽器。也就是說,該方法并不支持 IE 8 及之前版本的瀏覽器。
下圖是不同瀏覽器的不同版本對 getElementsByClassName() 方法的支持情況:

由于國內的生產環境中,依舊存在使用 IE 8 及之前版本瀏覽器的情況。所以,我們需要自定義 getElementsByClassName() 方法解決瀏覽器的兼容問題。
```javascript
function getElementsByClassName(element, names) {
}
```
上述自定義兼容方法接受兩個參數,element 參數表示調用 getElementsByClassName() 方法的對象(目前為 Document 對象),names 參數表示所要定位元素的 class 屬性值列表。
```javascript
function getElementsByClassName(element, names) {
// 檢測 getElementsByClassName() 是否可用
if (element.getElementsByClassName) {
// 優先使用 W3C 規范
return element.getElementsByClassName(names);
}else {
// 人為解決 IE 8 之前版本不兼容問題
}
}
```
這里我們要優先使用 W3C 規范的方法。所以,需要先判斷當前瀏覽器環境是否存在 getElementsByClassName() 方法。
如果存在,就使用原本的 getElementsByClassName() 方法。如果不存在,就使用自定義代碼來實現。
```javascript
function getElementsByClassName(element, names) {
// 檢測 getElementsByClassName() 是否可用
if (element.getElementsByClassName) {
// 優先使用 W3C 規范
return element.getElementsByClassName(names);
}else {
// 人為解決 IE 8 之前版本不兼容問題
// 獲取所有后代元素節點
var elements = element.getElementsByTagName('*');
// 定義空數組
var result = [];
var element, classNameStr, flag;
// 將樣式名稱改為數組類型
names = names.split(' ');
// 循環遍歷所有元素節點
for (var i=0; element = elements[i]; i++) {
// 獲取每個元素節點的樣式名稱
classNameStr = ' ' + element.className + ' ';
// 開啟開關
flag = true;
// 循環遍歷所有的樣式名稱
for (var j=0, name; name = names[j]; j++) {
// 判斷當前元素節點的樣式名稱中是否包含指定的樣式名稱
if (classNameStr.indexOf(' ' + name + ' ') == -1){
// 如果不包含,則關閉開關,并且結束循環
flag = false;
break;
}
}
// 判斷當前元素節點是否包含指定樣式名稱
if (flag) {
// 如果包含,則將當前元素節點添加到數組中
result.push(element);
}
}
// 返回數組(所有包含指定樣式名稱的元素節點)
return result;
}
}
```
## 通過 CSS 選擇器定位元素
CSS 中的選擇器可以很便利地定位 HTML 頁面元素,DOM 的標準規范中也提供類似的方法。
- querySelector(): 定位匹配選擇器的第一個元素。
- querySelectorAll(): 定位匹配選擇器的所有元素。
#### querySelector() 方法
其語法格式如下:
```javascript
element = document.querySelector(selectors);
```
在上述語法中,selectors 是參數,表示選擇器,可以包含一個或多個 CSS 選擇器,多個則以逗號分隔。element 是返回值,表示定位元素的集合,匹配的第一個元素。
下面是使用 querySelector() 方法的示例代碼:
```javascript
var btn = document.querySelector(’#btn');
// 獲取定位元素的 class 屬性值
var className = btn.className;
// 添加 animate 動畫樣式
className += ' animate';
// 將新的 class 屬性值設置
btn.className = className;
```
上述代碼通過 querySelector() 方法定位 HTML 頁面中 id 屬性值為 btn 的元素,并為其元素的 class 屬性添加 animate 樣式。
#### querySelectorAll() 方法
其語法格式如下:
```javascript
elements = document.querySelectorAll(selectors);
```
在上述語法中,selectors 是參數,表示選擇器,可以包含一個或多個 CSS 選擇器,多個則以逗號分隔。elements 是返回值,表示定位元素的集合,是一個 NodeList 集合。
下面是使用 querySelectorAll() 方法的示例代碼:
```javascript
var elems = document.querySelectorAll('button');
// 循環遍歷所有元素
for (var i=0; i<elems.length; i++) {
var elem = elems[i];
var className = elem.className;
className += ' animate';
elem.className = className;
}
```
上述代碼通過 querySelectorAll() 方法定位 HTML 頁面中元素名為 button 的元素,并遍歷所有得到的元素,為其元素的 class 屬性添加 animate 樣式。
## 節點集合 NodeList
NodeList 是一組元素節點的集合,每個節點具有相應的索引值(從 0 開始的數字,類似于數組)。
元素節點在 NodeList 集合中存儲的順序與它們在 HTML 頁面中的順序保持一致。
NodeList 的屬性 length 表示 NodeList 對象中包含的節點個數。方法 item(index) 表示返回 NodeList 對象中指定索引的節點。如果索引值越界,則返回 null。
NodeList 集合分為兩種: 動態 NodeList 和靜態 NodeList。
### 動態的 NodeList 集合
所謂動態的 NodeList 集合,就是如果文檔中的節點樹發生變化,則已經存在的 NodeList 對象也可能會變化。
以下幾種定位 HTML 頁面元素的方法返回的都是動態的 NodeList 集合。
- getElementsByName()方法:通過頁面元素的 name 屬性值定位元素。
- getElementsByTagName()方法:通過頁面元素的元素名定位元素。
- getElementsByClassName()方法:通過頁面元素的 class 屬性值定位元素。
我們可以通過以下示例代碼,體驗動態 NodeList 集合的特點:
```javascript
var elems = document.getElementsByTagName('button');
console.log(elems.length);// 輸出 3
// 添加一個新的button按鈕
var btn = document.createElement('button');
btn.setAttribute('class','button');
var text = document.createTextNode('New Button');
btn.appendChild(text);
var div = document.getElementsByClassName('button-group')[0];
div.appendChild(btn);
console.log(elems.length);// 輸出 4
```
上述代碼通過 getElementsByTagName() 方法定位 HTML 頁面中所有的 button 元素,測試打印 button 元素的個數是 3 個。
然后,我們創建一個新的 button 元素,并且將其添加到 HTML 頁面中,再測試打印 button 元素的個數是 4 個。
> **值得注意的是:** 我們在第二次測試打印 button 元素的個數時,并沒有重新定位 HTML 頁面中的 button 元素。
### 靜態 NodeList 集合
所謂靜態 NodeList 集合,就是對文檔對象模型的任何改動都不會影響集合的內容。
querySelectorAll() 方法定位 HTML 頁面元素所返回的 NodeList 集合就是靜態 NodeList 集合。
我們可以通過以下示例代碼,體驗靜態 NodeList 集合的特點:
```javascript
var elems = document.querySelectorAll('button');
console.log(elems.length);// 輸出 3
// 添加一個新的button按鈕
var btn = document.createElement('button');
btn.setAttribute('class','button');
var text = document.createTextNode('New Button');
btn.appendChild(text);
var div = document.getElementsByClassName('button-group')[0];
div.appendChild(btn);
console.log(elems.length);// 輸出 3
```
上述代碼通過 querySelectorAll() 方法定位 HTML 頁面中所有的 button 元素,測試打印 button 元素的個數是 3 個。
然后,我們創建一個新的 button 元素,并且將其添加到 HTML 頁面中,再測試打印 button 元素的個數依舊是 3 個。
## 定位頁面元素屬性
Document 對象也提供了一些屬性,來定位 HTML 頁面中一些比較特殊的元素。
- documentElement:獲取 HTML 頁面中的 `<html>` 元素。
- head:獲取 HTML 頁面中的 `<head>` 元素。
- title:獲取 HTML 頁面中的 `<title>` 元素。
- body:獲取 HTML 頁面中的 `<body>` 元素。
- links:獲取 HTML 頁面中的所有 `<a>` 元素。
- images:獲取 HTML 頁面中的所有 `<img>` 元素。
我們可以定義一個包含以上元素的 HTML 頁面,然后通過以下示例代碼進行測試:
```javascript
console.log(document.documentElement);
console.log(document.head);
console.log(document.body);
console.log(document.title);
console.log(document.links);
console.log(document.images);
```
- 關于
- 第一章 DOM 是什么
- 第一節 DOM 介紹
- 第二節 DOM 樹結構
- 第二章 Document 對象
- 第一節 Document 對象介紹
- 第二節 定位頁面元素
- 第三節 創建頁面元素
- 第三章 Node 對象
- 第一節 Node 對象介紹
- 第二節 判斷節點類型
- 第三節 遍歷節點
- 第四節 插入節點
- 第五節 刪除節點
- 第六節 替換節點
- 第七節 復制節點
- 第八節 textContent 屬性
- 第四章 Element 對象
- 第一節 Element 對象介紹
- 第二節 DOM 元素樹
- 第三節 定位頁面元素
- 第四節 遍歷元素
- 第五節 屬性操作
- 第六節 innerHTML 屬性
- 第五章 樣式操作
- 第一節 獲取內聯樣式
- 第二節 獲取外聯樣式表
- 第三節 獲取 class 屬性
- 第四節 獲取當前有效樣式
- 第五節 設置內聯樣式
- 第六節 設置 class 屬性
- 第七節 Element 對象的樣式屬性
- 第六章 事件
- 第一節 什么是事件
- 第二節 注冊事件
- 第三節 移除注冊事件
- 第四節 Event 事件對象
- 第五節 獲取目標元素
- 第六節 阻止默認行為
- 第七節 獲取鼠標坐標
- 第八節 事件流
- 第九節 事件委托
- 第七章 表單操作
- 第一節 獲取表單
- 第二節 表單操作
- 第三節 表單驗證
- 第四節 表單提交
- 第八章 BOM
- 第一節 BOM 是什么
- 第二節 Window 對象
- 第三節 Navigator 對象
- 第四節 History 對象
- 第五節 Location 對象
- 第六節 定時器