Javascript中DOM常見API

前言:盡管現在有很多優秀的框架,大大簡化了我們的DOM操作,但是我們仍然要學好DOM知識來寫原生JS,從根本上去理解,才更能在解決問題時舉重若輕。

一、什么是DOM

D(document)O(object)M(model) 文檔對象模型。

DOM(文檔對象模型)是HTML和XML文檔的編程接口。它提供了對文檔的結構化的表述,并定義一種方式可以使從程序中對該結構進行訪問,從而改變文檔的結構、樣式和內容。DOM將文檔解析為一個由節點和對象(包含屬性和方法的對象)組成的結構集合。

上述說法是MDN的解釋,太官方,我們來換種說法來解釋。

DOM就是一種想象的樹形結構,它的作用是將網頁轉為一個 JavaScript 對象,從而可以用腳本進行各種操作(比如增刪內容)。

image

如上圖,是我們文檔的樹形結構,我們通過DOM模型將上述結構一一映射成節點(通過構造函數把頁面中的節點變成實例對象,dom就是這樣把文檔變成對象的),這些節點就又構成了節點樹,也就是我們說的想象中的那棵DOM Tree。

二、Node

DOM 的最小組成單位叫做節點(node)。文檔的樹形結構(DOM 樹),就是由各種不同類型的節點組成。

節點主要有7種類型:

  • Document:整個文檔樹的根節點
  • Document:doctype標簽節點,如<!DOCTYPE html>
  • Element:網頁的各種Html標簽,比如<body><div>
  • Attribute:網頁元素的屬性
  • Text:標簽之間或者標簽包含的文本
  • Comment:注釋
  • DocunmentFragment:文檔的片段

所以文檔樹對應的節點樹如同下圖:

image

注:DOM樹有3種層級結構:

  • 父節點關系(parentNode):直接的上級節點
  • 子節點關系(childNodes):直接的下級節點
  • 兄弟關系(sibling):擁有同一個父節點的同級節點

值得注意的是,在上圖中只有根節點也就是<html>對應的節點沒有父節點。

三、Node接口

瀏覽器提供一個原生的節點對象Node,上面的7種節點均繼承了Node,因此具有一些共同的屬性和方法。這是DOM操作的基礎。

image

1、屬性

1.1 Node.prototype.nodeType

nodeType屬性返回一個整數值,表示節點的類型。

image

如上圖,我們獲取當前頁面的body標簽下的第一個孩子,是一個div標簽,然后我們通過nodeType來看一下它的節點類型,結果返回了一個數字1,這代表著是一個Element節點。

【至于為什么會是返回一個數字而不是簡單明了的返回Element,這也是由于歷史原因,早期計算機內存緊張,為了節省內存使用了并無規律的數字】

常見的有以下:

Node.ELEMENT_NODE:1

Node.ATTRIBUTE_NODE:2

Node.TEXT_NODE:3

Node.COMMENT_NODE:8

Node.DOCUMENT_NODE:9

Node.DOCUMENT_TYPE_NODE:10

Node.DOCUMENT_FRAGMENT_NODE:11

1.2 Node.prototype.nodeName

nodeName屬性返回節點名稱

image

注:在元素節點中,返回名稱基本都是大寫,只有<svg>標簽返回的是小寫。

1.3 Node.prototype.nodeValue

nodeValue屬性返回一個字符串,表示當前節點本身的文本值,該屬性可讀寫。

只有文本節點(text)、注釋節點(comment)和屬性節點(attr)有文本值,因此這三類節點的nodeValue可以返回結果,其他類型的節點一律返回null

// html 代碼如下
// <div id="d1">hello world</div>
var div = document.getElementById('d1');
div.nodeValue // null
div.firstChild.nodeValue //"hello world"

1.4 Node.prototype.textContent

textContent返回節點及后代節點的文本 ,即獲取文本

這里和innerText一起講:

早期并沒有獲取文本的API ,導致編碼很繁瑣,所以后來IE自己添加了一個API就是innerText,然后火狐和opera也推出了textContent

兩者的區別:

  • textContent會獲取所有元素的內容,包括<script><style>元素,然而innerText不會獲取這些內容。
  • innerText可以意識到樣式,它不會返回樣式為display:none也就是隱藏的文本,而textContent會。
  • 由于innerText會意識到樣式,也就是會受樣式的影響,因此會觸發重排(reflow)導致性能低,而textContent不會。
  • textContent不同, 在 Internet Explorer (對于小于等于 IE11 的版本) 中對innerText進行修改, 不僅會移除當前元素的子節點,而且還會永久性地破壞所有后代文本節點(所以不可能將節點再次插入到任何其他元素或同一元素中).

1.5 Node.prototype.nextSibling

Node.nextSibling屬性返回緊跟在當前節點后面的第一個同級節點。如果當前節點后面沒有同級節點,則返回null

image

值得注意的是,該屬性還包括文本節點和注釋節點(``)。因此如果當前節點后面有空格或者回車,該屬性會返回一個文本節點,內容為空格或回車。

document.body.nextSibling返回了文本節點或者注釋節點,而我們需要獲得是元素節點, 也可以用document.prototype.nextElementSibling直接獲取該節點后面最接近的同級元素節點。

1.6 Node.prototype.previousSibling

previousSibling屬性返回當前節點前面的、距離最近的一個同級節點。如果當前節點前面沒有同級節點,則返回null

Node.prototype.previousElementSibling 前一個同級元素節點

其他同1.5 一致

1.7 Node.prototype.firstChild,Node.prototype.firstElementChild

firstChild屬性返回當前節點的第一個子節點,如果當前節點沒有子節點,則返回null
firstElementChild屬性返回當前節點的第一個元素節點。

1.8 Node.prototype.lastChild,Node.prototype.lastElementChild

lastChild屬性返回當前節點的最后一個子節點,如果當前節點沒有子節點,則返回null
lastElementChild屬性返回當前節點的最后一個元素節點。

1.9 Node.prototype.childNodes

childNodes屬性返回一個類似數組的對象(NodeList集合),成員包括當前節點的所有子節點。

image

值得注意的是,除了元素節點,childNodes屬性的返回值還包括文本節點和注釋節點。如果當前節點不包括任何子節點,則返回一個空的NodeList集合。由于NodeList對象是一個動態集合,一旦子節點發生變化,立刻會反映在返回結果之中。

1.10 Node.prototype.children

children屬性返回一個類似數組的對象(HTMLCollection),成員包括當前節點的所有子元素節點。

image

值得注意的是,這里就不會返回文本節點和注釋節點了,它只會返回元素節點。由于HTMLCollection集合是動態集合,一旦子節點發生變化,立刻會反映在返回結果之中。

小tips : NodelistHTMLCollection 集合的區別

  1. NodeList可以包含各種類型的節點,HTMLCollection只能包含 HTML 元素節點.
  2. NodeList 實例可能是動態集合,也可能是靜態集合。目前,只有Node.childNodes返回的是一個動態集合,其他的NodeList 都是靜態集合。而HTMLCollection實例都是動態集合,節點的變化會實時反映在集合中.
  3. NodeList接口不同,HTMLCollection沒有forEach方法,只能使用for循環遍歷。

2、方法

2.1 Node.prototype.appendChild()

appendChild方法就是接受一個節點對象作為參數,將其作為最后一個子節點,插入到當前節點 。該方法的返回值就是插入的子節點。

注意:

1、如果參數節點是 DOM 已經存在的節點,appendChild方法會將其從原來的位置移動到新位置。

2、如果appendChild方法的參數是DocumentFragment節點,那么插入的是DocumentFragment的所有子節點,而不是DocumentFragment節點本身。返回值是一個空的DocumentFragment .

2.2 Node.prototype.hasChildNodes()

hasChildNodes方法返回一個布爾值,表示當前節點是否有子節點。

注意:子節點包括所有類型的節點,并不僅僅是元素節點。哪怕節點只包含一個空格,hasChildNodes方法也會返回true

判斷一個節點是否有子節點,有以下3種方法:

1、node.hasChildNodes()

2、node.firstChild ! == null

3、node.childNodes && node.childNodes.length > 0

2.3 Node.prototype.cloneNode()

cloneNode方法拷貝一個節點,并且可以接受一個布爾值,來表示是否同時拷貝子節點。它的返回值是一個克隆出來的新節點。

image
image

深拷貝:深入進去全部拷貝,包括子節點。

淺拷貝:只拷貝節點本身。

值得注意的是,該方法返回的節點不在文檔中,無任何父節點,必須用如appendChild()等方法添加。

2.4 Node.prototype.insertBefore()

insertBefore方法用于將某個節點插入父節點內部的指定位置。

insertBefore方法接受兩個參數,第一個參數是所要插入的節點newNode,第二個參數時父節點parentNode內部的一個子節點referenceNodenewNode將插在referenceNode這個子節點的前面。返回值是插入的新節點newNode.

2.5 Node.prototype.removeChild()

removeChild方法接受一個子節點作為參數,用于從當前節點移除該子節點。返回值是移除的子節點。

值得注意的是,被移除的節點依然存在于內存之中,但不再是DOM的一部分。所以,一個節點移除以后,依然可以使用它,比如插入到另一個節點下面。

如果參數節點不是當前節點的子節點,removeChild方法將報錯。

2.6 Node.prototype.replaceChild()

replaceChild方法用于將一個新的節點,替換當前節點的某一個子節點。

創造一個新兒子取代掉舊兒子,舊兒子去哪兒了?舊兒子去內存了。

2.7 Node.prototype.contains()

contains方法返回一個布爾值,表示參數節點是否為該節點的后代節點。

2.8 Node.prototype.isEqualNode(),Node.prototype.isSameNode()

isEqualNode方法返回一個布爾值,用于檢查兩個節點是否相等。所謂相等的節點,指的是兩個節點的類型相同、屬性相同、子節點相同。
isSameNode方法返回一個布爾值,表示兩個節點是否為同一個節點。

image

所以說,isSameNode就等同于 ===嚴格相等運算符。

2.9 Node.prototype.normalize()

normailize方法用于清理當前節點內部的所有文本節點(text)。它會去除空的文本節點,并且將毗鄰的文本節點合并成一個,也就是說不存在空的文本節點,以及毗鄰的文本節點

四、Document接口

document節點對象代表整個文檔,每張網頁都有自己的document對象。window.document屬性就指向這個對象。只要瀏覽器開始載入 HTML 文檔,該對象就存在了,可以直接使用。

document對象有不同的辦法可以獲取。

1、屬性

1.1 用于指向其他節點(快捷獲取某些特殊節點)的屬性

  • document.doctype 指向<DOCTYPE>節點,即文檔類型節點。
  • document.documentElement指向 DOM 的 html節點
  • document.activeElement指向獲得焦點的那個節點
  • document.fullscreenElement返回當前以全屏狀態展示的 DOM 元素。
  • document.body指向<body>節點
  • document.head指向<head>節點。
  • document.scrollingElement返回文檔的滾動元素。
  • ……

1.2 返回文檔特定元素的偽數組集合的屬性

  • document.links屬性返回當前文檔所有設定了href屬性的<a><area>節點。
  • document.forms屬性返回所有<form>表單節點。
  • document.images屬性返回頁面所有<img>圖片節點。
  • document.scripts屬性返回所有<script>節點。
  • document.styleSheets屬性返回文檔內嵌或引入的樣式表集合
  • ……

以上均為動態集合,而且除了document.styleSheets,以上的集合屬性返回的都是HTMLCollection實例。

1.3 返回文檔信息的屬性

  • document.documentURI和document.URL屬性都返回一個字符串,表示當前文檔的網址。
  • document.domain屬性返回當前文檔的域名,不包含協議和接口。
  • document.Location對象是瀏覽器提供的原生對象,提供 URL 相關的信息和操作方法。
  • document.title屬性返回當前文檔的標題。
  • document.characterSet屬性返回當前文檔的編碼,比如UTF-8
  • document.referrer屬性返回一個字符串,表示當前文檔的訪問者來自哪里.
  • ……

1.4 返回文檔狀態的屬性

  • document.hidden屬性返回一個布爾值,表示當前頁面是否可見。
  • document.visibilityState返回文檔的可見狀態。
  • ……

2、方法

  • document.open方法清除當前文檔所有內容,使得文檔處于可寫狀態,供document.write方法寫入內容。
  • document.close方法用來關閉document.open()打開的文檔。
  • document.write方法用于向當前文檔寫入內容。
  • document.writeln方法與write方法完全一致,除了會在輸出內容的尾部添加換行符。
  • document.querySelector接受一個 CSS 選擇器作為參數,返回匹配該選擇器的元素節點
  • document.querySelectorAll方法與querySelector用法類似,區別是返回一個NodeList對象,包含所有匹配給定選擇器的節點。
  • document.getElementsByTagName搜索 HTML 標簽名,返回符合條件的元素。
  • document.getElementsByClassName 返回一個類似數組的對象(HTMLCollection實例),包括了所有class名字符合指定條件的元素,元素的變化實時反映在返回結果中。
  • document.getElementsByName方法用于選擇擁有name屬性的 HTML 元素,返回一個類似數組的的對象(NodeList實例).
  • document.getElementById方法返回匹配指定id屬性的元素節點
  • document.createElement方法用來生成元素節點,并返回該節點。
  • document.createTextNode方法用來生成文本節點(Text實例)
  • document.createDocumentFragment方法生成一個空的文檔片段對象(DocumentFragment實例)。
  • document.hasFocus方法返回一個布爾值,表示當前文檔之中是否有元素被激活或獲得焦點。
  • ……

五、Element接口

1、屬性

  • Element.id屬性返回指定元素的id屬性,該屬性可讀寫。
  • Element.tagName屬性返回指定元素的大寫標簽名
  • Element.title屬性用來讀寫當前元素的 HTML 屬性title
  • Element.attributes屬性返回一個類似數組的對象,成員是當前元素節點的所有屬性節點
  • Element.className屬性用來讀寫當前元素節點的class屬性。
  • Element.classList返回一個偽數組,成員是當前元素節點的每個class
  • Element.innerHTML屬性返回一個字符串,等同于該元素包含的所有 HTML 代碼。
  • Element.clientHeight屬性返回一個整數值,表示元素節點的 CSS 高度
  • Element.clientWidth屬性返回元素節點的 CSS 寬度,同樣只對塊級元素
  • Element.scrollHeight屬性返回一個整數值(小數會四舍五入),表示當前元素的總高度(單位像素),包括溢出容器、當前不可見的部分。
  • Element.scrollWidth屬性表示當前元素的總寬度(單位像素),其他地方都與scrollHeight屬性類似。
  • Element.children屬性返回一個類似數組的對象(HTMLCollection實例),包括當前元素節點的所有子元素。
  • Element.childElementCount屬性返回當前元素節點包含的子元素節點的個數,與Element.children.length的值相同。
  • ……

2、方法

  • getAttribute()讀取某個屬性的值
  • getAttributeNames()返回當前元素的所有屬性名
  • setAttribute()寫入屬性值
  • hasAttribute()某個屬性是否存在
  • hasAttributes()當前元素是否有屬性
  • removeAttribute()刪除屬性
  • Element.querySelector接受 CSS 選擇器作為參數,返回父元素的第一個匹配的子元素。
  • Element.querySelectorAll接受 CSS 選擇器作為參數,返回一個NodeList實例,包含所有匹配的子元素。
  • Element.remove方法繼承自 ChildNode 接口,用于將當前元素節點從它的父節點移除。
  • Element.getBoundingClientRect方法返回一個對象,提供當前元素節點的大小、位置等信息,基本上就是 CSS 盒狀模型的所有信息
  • Element.addEventListener():添加事件的回調函數
  • Element.removeEventListener():移除事件監聽函數
  • Element.dispatchEvent():觸發事件
  • ……
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,556評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,463評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,009評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,778評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,218評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,436評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,969評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,795評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,993評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,229評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,659評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,917評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,687評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,990評論 2 374

推薦閱讀更多精彩內容