DOM擴充套件
儘管DOM作為API已經非常完善了,但是為了實現更多的功能,仍然會有一些標準或專有的擴充套件。對DOM的兩個主要擴充套件是Selectors API(選擇符API)和HTML5。
一、選擇符API
Selectors API是由W3C發起制定的一個標準,致力於讓瀏覽器原生支援CSS查詢。其核心的兩個方法:querySelector()
和querySelectorAll()
。
1. querySelector()方法
querySelector()
接受一個CSS選擇符,返回與該模式匹配的第一個元素,如果沒有找到匹配的元素返回null。
示例:
document.querySelector("body");
document.querySelector("#content");
document.querySelector(".bd");
- 1
- 2
- 3
- 1
- 2
- 3
2. querySelectorAll()方法
querySelectorAll()接受一個CSS選擇符,返回與該模式匹配的NodeList例項,如果沒有找到匹配的元素返回null。
示例:
var lis = document.querySelectorAll("ul li");
// 獲取第一個li
lis.item(0); // 等價於:lis[0];
- 1
- 2
- 3
- 1
- 2
- 3
注意:上述兩個函式如果傳入不支援的選擇符,會丟擲錯誤。
3. matchesSelector()方法
matchesSelector()
方法大部分瀏覽器未實現,可使用matches()或者使用各個瀏覽器實驗性的實現。
function matchesSelector(element, selec)
- 1
- 1
function matchesSelector(element, selector){
if (element.matchesSelector){
return element.matchesSelector(selector);
} else if (element.msMatchesSelector){
return element.msMatchesSelector(selector);
} else if (element.mozMatchesSelector){
return element.mozMatchesSelector(selector);
} else if (element.webkitMatchesSelector){
return element.webkitMatchesSelector(selector);
} else if(ele.matches){
return ele.matches(selector);
} else{
throw new Error("Not supported.");
}
}
matchesSelector(document.body, "body"); // true
matchesSelector(document.body, "body div"); // false
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
二、元素遍歷
對於元素間的空格,各瀏覽器對於childNodes和firstChild等屬性處理行為不一致,為了彌補差異,Element Traversal新定義了一組屬性。
示例:
<p>李剛</p>
<ul>
<li>item1</li>
<li>item2</li>
<li>item3</li>
<li>item4</li>
<li>item5</li>
</ul>
<p id="blog">http://blog.csdn.net/ligang2585116</p>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
屬性 | 說明 | 示例 |
---|---|---|
childElementCount | 子元素(不包含文字節點和註釋)的個數 | 5 |
firstElementChild | 指向第一個子元素,firstChild的元素版 |
<li>Item 1</li> |
lastElementChild | 指向最後一個子元素,lastChild的元素版 |
<li>Item 5</li> |
previousElementSibling | 指向前一個同輩元素,previousSibling的元素版 |
<p>李剛</p> |
nextElementSibling | 指向後一個同輩元素,nextSibling的元素版 |
<p id="blog">http://blog.csdn.net/ligang2585116</p> |
var ul = document.querySelector("ul");
ul.firstChild; // #text
ul.lastChild; // <li>Item 5</li>
ul.previousSibling; // #text
ul.nextSibling; // #text
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
三、HTML5
1. 與類相關的擴充
(1)getElementsByClassName("包含一或多個類名的字串")
document.getElementsByClassName("bj"); // 取得類中包含“bj”的元素
document.getElementsByClassName("bj bd"); // 取得類中同時包含“bj”和“bd”的元素
- 1
- 2
- 1
- 2
(2)classList屬性
在操作類名時,需要通過className屬性新增、刪除和替換型別名。因為className中是一個字串,所以即使只修改字串的一部分,也必須每次都設定整個字串的值。
<div class="bd user">ligang</div>
- 1
- 1
示例:className方式
var div = document.getElementsByClassName("bd")[0];
var classNames = div.className.split(/\s+/);
// 查詢要刪除的類名"user"
var index = classNames.indexOf("user");
// 刪除類名"user"
classNames.splice(index, 1);
// 重新設定className
div.className = classNames;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
示例:classList方式
var div = document.getElementsByClassName("bd")[0];
div.classList.remove("user");
- 1
- 2
- 1
- 2
classList屬性是DOMTokenList的例項,其含有length屬性。
屬性 | 說明 |
---|---|
add(value) | 將給定的字串新增到列表中。如果已存在,就不新增了 |
contains(value) | 表示列表中是否存在給定的值 |
remove(value) | 從列表中刪除給定的字串 |
toggle(value) | 如果列表中已存在給定的值,刪除它;如果不存在,新增它 |
有了classList屬性,除非需要刪除全部所有類名,或者完全重寫元素的class屬性,否則也就用不到className屬性了。
2. 焦點管理
document.activeElement
屬性始終會引用DOM中當前獲得了焦點的元素。
示例:
var btn = document.getElementById("myBtn");
btn.focus();
console.log(btn.hasFocus()); // true
console.log(document.activeElement === btn); // true
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
預設情況下,文件剛剛載入完成時,document.activeElement
中儲存的是document.body
元素的引用。文件載入期間,document.activeElement
為null。
查詢文件獲知哪個元素獲得了焦點,以及確定文件是否獲得了焦點,這兩個功能最重要的用途是提高Web應用的無障礙性。無障礙Web應用的一個重要標誌就是恰當的焦點管理,而確切地知道哪個元素獲得了焦點是一個極大的進步。
3. HTMLDocument的變化
(1)readyState屬性
- loading:正在載入文件;
- complete:已經載入完文件。
使用document.readyState的最恰當方式,就是通過它來實現一個指示文件已經載入完成的指示器。
(2)相容模式 document.compatMode
告知開發人員瀏覽器採用了哪種渲染模式。
- CSS1Compat:標準模式;
- BackCompat:混雜模式。
(3)head屬性
Html5新增了document.head
屬性,引用文件的<head>
元素。
var head = document.head || document.getElementsByTagName("head")[0];
- 1
- 1
4. 字符集屬性
- document.charset:文件中實際使用的字符集,也可以用來指定新字符集;
- document.defaultCharset:表示根據瀏覽器及作業系統的設定,當前文件預設的字符集應該是什麼,注意相容性。
5. 自定義資料屬性
HTML5規定可以為元素新增非標準的屬性,但要新增字首data-,目的是為元素提供與渲染無關的資訊,或者提供語義資訊。
<div id="div" data-status="1" data-appId="123" data-customName="ligang">哈哈</div>
- 1
- 1
新增了自定義屬性後,可以通過元素的dataset屬性來訪問自定義屬性的值。
var div = document.getElementById("div");
var dataset = div.dataset;
console.log(dataset.appid); // 123
console.log(dataset.customname); // "ligang" 注意,都是小寫
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
6. 插入標記
DOM操作文件插入HTML標記非常複雜,因為其不僅要建立一系列DOM節點,而且還要小心地按照正確順序進行連線。詳見:DOM
示例:建立a標籤並插入到body
var a = document.createElement("a");
a.href = "http://blog.csdn.net/ligang2585116";
a.text = "http://blog.csdn.net/ligang2585116";
document.body.appendChild(a);
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
使用插入標記的技術,直接插入HTML字串不僅簡單而且速度更快。
(1)innerHTML屬性
讀模式:返回撥用元素的所有節點(包括元素、註釋和文字節點)對應的HTML標記;
寫模式:根據指定的值建立新的DOM樹,然後用這個DOM樹完全替換呼叫元素原先的所有子節點。
示例:建立a標籤並插入到body
document.body.innerHTML += '<a href="http://blog.csdn.net/ligang2585116">http://blog.csdn.net/ligang2585116</a>'
- 1
- 1
注意:上述使用“+=”,因為寫模式下,innerHTML的值會被解析為DOM子樹,替換呼叫元素原來的所有子節點。
說明:使用innerHTML插入的字串開頭是一個無作用域的元素(<script>、<style>
)時,IE會在解析這個字串前先刪除該元素。
div.innerHTML = "<script>console.logt('hi')</script>"; // 無效
div.innerHTML = "<div> </div><script>console.logt('hi')</script>"; // 有效
div.innerHTML = "<input type=\"hidden\"><script>console.logt('hi')</script>"; // 有效
- 1
- 2
- 3
- 1
- 2
- 3
(2)outerHTML屬性
讀模式:返回撥用它的元素及所有節點(包括元素、註釋和文字節點)對應的HTML標記;
寫模式:根據指定的值建立新的DOM樹,然後用這個DOM樹完全替換呼叫元素。
示例:
<div id="blog">
<!-- blog address -->
<a href="http://blog.csdn.net/ligang2585116">blog</a>
</div>
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
var div = document.getElementById("blog");
div.outerHTML; // 整個innerHTML內容+div本身
div.outerHTML = "<a href=\"http://blog.csdn.net/ligang2585116\">blog</a>"; // 整個div會被a標籤替換掉
// 等價於
var a = document.createElement("a");
a.href = "http://blog.csdn.net/ligang2585116";
a.text = "blog";
div.parentNode.replaceChild(a, div);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
(3)記憶體與效能問題
使用上述節點方法可能會導致瀏覽器的記憶體佔用問題。在刪除帶有事件處理程式或引用了其他JavaScript物件子樹時,就會導致記憶體佔用問題。在使用innerHTML、outerHTML等方法時,最好先刪除要替換的元素的所有事件處理程式和JavaScript物件屬性。
7. scrollIntoView()方法
如何滾動頁面也是DOM規範沒有解決的一個問題,HTML5最終選擇了scrollIntoView
作為標準。 scrollIntoView()
可以在任何元素上呼叫。預設或傳入true,視窗會滾動讓呼叫元素與視口頂部儘可能齊平;傳入false,呼叫元素儘可能會全部出現在視窗中。
document.forms[0].scrollIntoView();
- 1
- 1
當頁面發生變化時,一般會用這個方法來吸引使用者的注意力。實際上,為某個元素設定焦點也會導致瀏覽器滾動並顯示出獲得焦點的元素。
四、專有擴充套件
1. children屬性
children屬性與childNodes沒有什麼區別。
2. contains()方法
判斷某個節點是不是另一個節點的後代。
document.body.contains(div); // true
- 1
- 1
掩碼 | 節點關係 |
---|---|
1 | 無關(給定的節點不再當前文件中) |
2 | 居前(給定的節點在DOM樹中位於參考節點之前) |
4 | 居後(給定的節點在DOM樹中位於參考節點之後) |
8 | 包含(給定的節點是參考節點的祖先) |
16 | 被包含(給定的節點是參考節點的後代) |
示例:通用的contains函式
function contains(refNode, otherNode){
if (typeof refNode.contains == "function" &&
(!client.engine.webkit || client.engine.webkit >= 522)){
return refNode.contains(otherNode);
} else if (typeof refNode.compareDocumentPosition == "function"){
return !!(refNode.compareDocumentPosition(otherNode) & 16);
} else {
var node = otherNode.parentNode;
do {
if (node === refNode){
return true;
} else {
node = node.parentNode;
}
} while (node !== null);
return false;
}
}
console.log(contains(document.documentElement, document.body)); // true
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
3. 插入文字
innerText
和outerText
並沒有被納入HTML5。
其對文字進行操作,使用方式類似於innerHTM
和outerHTML
。
4. 滾動
HTML5將scrollIntoView()方法納入規範之後,仍還有其他幾個專有方法可以在不同的瀏覽器中使用。
(1)scrollIntoViewIfNeeded(alignCenter)
:只在當前元素視口中不可見的情況下,才滾動瀏覽器視窗或容器元素,最終讓它可見。如果當前元素在視口中可見,這個方法什麼也不做。true,儘量將元素在顯示視口中部(垂直方向)。
(2)scrollByLines(lineCount)
:將元素的內容滾動指定的行高。
(3)scrollByPages(pageCount)
:將元素的內容滾動指定的頁面高度,具體高度由元素的高度決定。
注意:scrollIntoView()
和scrollIntoViewIfNeeded()
的作用物件是元素的容器;scrollByLines()
和scrollByPages()
影響的則是元素自身。
相關文章
- DOM部分擴充套件套件
- DOM擴充套件之HTML5套件HTML
- HTML5新增API之DOM 擴充套件HTMLAPI套件
- kotlin 擴充套件(擴充套件函式和擴充套件屬性)Kotlin套件函式
- WCF擴充套件:行為擴充套件Behavior Extension套件
- 【Kotlin】擴充套件屬性、擴充套件函式Kotlin套件函式
- Sanic 擴充套件套件
- ORACLE 擴充套件Oracle套件
- 擴充套件工具套件
- 擴充套件歐幾里得套件
- 擴充套件ACL套件
- Lua擴充套件套件
- 照片擴充套件套件
- 擴充套件篇套件
- disable or 擴充套件套件
- 擴充套件表套件
- Mybatis擴充套件MyBatis套件
- JMeter 擴充套件開發:擴充套件 TCP 取樣器JMeter套件TCP
- ?用Chrome擴充套件管理器, 管理你的擴充套件Chrome套件
- ASP.NET Core擴充套件庫之Http通用擴充套件ASP.NET套件HTTP
- php7安裝redis擴充套件和memcache擴充套件PHPRedis套件
- 分類擴充套件套件
- 擴充套件表示式套件
- 新增php擴充套件PHP套件
- swift擴充套件ExtensionsSwift套件
- iOS 通知擴充套件iOS套件
- 可擴充套件性套件
- 19-擴充套件套件
- Nmap 擴充套件(四)套件
- Flask 自建擴充套件Flask套件
- 擴充套件包上傳套件
- 擴充套件知識套件
- php ubuntu 擴充套件PHPUbuntu套件
- greenplum擴充套件segment套件
- ios UIcolor擴充套件iOSUI套件
- 擴充套件BSGS/exBSGS套件
- SpringMVC 擴充套件SpringMVC套件
- 提高擴充套件性套件