Element
節(jié)點(diǎn)對(duì)象對(duì)應(yīng)網(wǎng)頁(yè)的 HTML 元素。每一個(gè) HTML 元素,在 DOM 樹(shù)上都會(huì)轉(zhuǎn)化成一個(gè)Element
節(jié)點(diǎn)對(duì)象(以下簡(jiǎn)稱元素節(jié)點(diǎn))。
元素節(jié)點(diǎn)的nodeType
屬性都是1
。
var p = document.querySelector('p');
p.nodeName // "P"
p.nodeType // 1
Element
對(duì)象繼承了Node
接口,因此Node
的屬性和方法在Element
對(duì)象都存在。
此外,不同的 HTML 元素對(duì)應(yīng)的元素節(jié)點(diǎn)是不一樣的,瀏覽器使用不同的構(gòu)造函數(shù),生成不同的元素節(jié)點(diǎn),比如<a>
元素的構(gòu)造函數(shù)是HTMLAnchorElement()
,<button>
是HTMLButtonElement()
。因此,元素節(jié)點(diǎn)不是一種對(duì)象,而是許多種對(duì)象,這些對(duì)象除了繼承Element
對(duì)象的屬性和方法,還有各自獨(dú)有的屬性和方法。
(1)Element.id
Element.id
屬性返回指定元素的id
屬性,該屬性可讀寫(xiě)。
// HTML 代碼為 <p id="foo">
var p = document.querySelector('p');
p.id // "foo"
注意,id
屬性的值是大小寫(xiě)敏感,即瀏覽器能正確識(shí)別<p id="foo">
和<p id="FOO">
這兩個(gè)元素的id
屬性,但是最好不要這樣命名。
(2)Element.tagName
Element.tagName
屬性返回指定元素的大寫(xiě)標(biāo)簽名,與nodeName
屬性的值相等。
// HTML代碼為
// <span id="myspan">Hello</span>
var span = document.getElementById('myspan');
span.id // "myspan"
span.tagName // "SPAN"
(3)Element.dir
Element.dir
屬性用于讀寫(xiě)當(dāng)前元素的文字方向,可能是從左到右("ltr"
),也可能是從右到左("rtl"
)。
(4)Element.accessKey
Element.accessKey
屬性用于讀寫(xiě)分配給當(dāng)前元素的快捷鍵。
// HTML 代碼如下
// <button accesskey="h" id="btn">點(diǎn)擊</button>
var btn = document.getElementById('btn');
btn.accessKey // "h"
上面代碼中,btn
元素的快捷鍵是h
,按下Alt + h
就能將焦點(diǎn)轉(zhuǎn)移到它上面。
(5)Element.draggable
Element.draggable
屬性返回一個(gè)布爾值,表示當(dāng)前元素是否可拖動(dòng)。該屬性可讀寫(xiě)。
(6)Element.lang
Element.lang
屬性返回當(dāng)前元素的語(yǔ)言設(shè)置。該屬性可讀寫(xiě)。
// HTML 代碼如下
// <html lang="en">
document.documentElement.lang // "en"
(7)Element.tabIndex
Element.tabIndex
屬性返回一個(gè)整數(shù),表示當(dāng)前元素在 Tab 鍵遍歷時(shí)的順序。該屬性可讀寫(xiě)。
tabIndex
屬性值如果是負(fù)值(通常是-1
),則 Tab 鍵不會(huì)遍歷到該元素。如果是正整數(shù),則按照順序,從小到大遍歷。如果兩個(gè)元素的tabIndex
屬性的正整數(shù)值相同,則按照出現(xiàn)的順序遍歷。遍歷完所有tabIndex
為正整數(shù)的元素以后,再遍歷所有tabIndex
等于0
、或者屬性值是非法值、或者沒(méi)有tabIndex
屬性的元素,順序?yàn)樗鼈冊(cè)诰W(wǎng)頁(yè)中出現(xiàn)的順序。
(8)Element.title
Element.title
屬性用來(lái)讀寫(xiě)當(dāng)前元素的 HTML 屬性title
。該屬性通常用來(lái)指定,鼠標(biāo)懸浮時(shí)彈出的文字提示框。
(1)Element.hidden
Element.hidden
屬性返回一個(gè)布爾值,表示當(dāng)前 HTML 元素的hidden
屬性的值。該屬性可讀寫(xiě),用來(lái)控制當(dāng)前元素是否可見(jiàn)。
var btn = document.getElementById('btn');
var mydiv = document.getElementById('mydiv');
btn.addEventListener('click', function () {
mydiv.hidden = !mydiv.hidden;
}, false);
注意,該屬性與 CSS 設(shè)置是互相獨(dú)立的。CSS 對(duì)當(dāng)前元素可見(jiàn)性的設(shè)置,Element.hidden
并不能反映出來(lái)。也就是說(shuō),這個(gè)屬性并不能用來(lái)判斷當(dāng)前元素的實(shí)際可見(jiàn)性。
CSS 設(shè)置的優(yōu)先級(jí)高于Element.hidden
。如果 CSS 指定了該元素不可見(jiàn)(display: none
)或可見(jiàn)(visibility: visible
),那么Element.hidden
并不能改變?cè)撛貙?shí)際的可見(jiàn)性。換言之,這個(gè)屬性只在 CSS 沒(méi)有明確設(shè)定當(dāng)前元素的可見(jiàn)性時(shí)才有效。
(2)Element.contentEditable,Element.isContentEditable
HTML 元素可以設(shè)置contentEditable
屬性,使得元素的內(nèi)容可以編輯。
<div contenteditable>123</div>
上面代碼中,<div>
元素有contenteditable
屬性,因此用戶可以在網(wǎng)頁(yè)上編輯這個(gè)區(qū)塊的內(nèi)容。
Element.contentEditable
屬性返回一個(gè)字符串,表示是否設(shè)置了contenteditable
屬性,有三種可能的值。該屬性可寫(xiě)。
"true"
:元素內(nèi)容可編輯"false"
:元素內(nèi)容不可編輯"inherit"
:元素是否可編輯,繼承了父元素的設(shè)置 Element.isContentEditable
屬性返回一個(gè)布爾值,同樣表示是否設(shè)置了contenteditable
屬性。該屬性只讀。
Element.attributes
屬性返回一個(gè)類(lèi)似數(shù)組的對(duì)象,成員是當(dāng)前元素節(jié)點(diǎn)的所有屬性節(jié)點(diǎn),詳見(jiàn)《屬性的操作》一章。
var p = document.querySelector('p');
var attrs = p.attributes;
for (var i = attrs.length - 1; i >= 0; i--) {
console.log(attrs[i].name + '->' + attrs[i].value);
}
上面代碼遍歷p
元素的所有屬性。
className
屬性用來(lái)讀寫(xiě)當(dāng)前元素節(jié)點(diǎn)的class
屬性。它的值是一個(gè)字符串,每個(gè)class
之間用空格分割。
classList
屬性返回一個(gè)類(lèi)似數(shù)組的對(duì)象,當(dāng)前元素節(jié)點(diǎn)的每個(gè)class
就是這個(gè)對(duì)象的一個(gè)成員。
// HTML 代碼 <div class="one two three" id="myDiv"></div>
var div = document.getElementById('myDiv');
div.className
// "one two three"
div.classList
// {
// 0: "one"
// 1: "two"
// 2: "three"
// length: 3
// }
上面代碼中,className
屬性返回一個(gè)空格分隔的字符串,而classList
屬性指向一個(gè)類(lèi)似數(shù)組的對(duì)象,該對(duì)象的length
屬性(只讀)返回當(dāng)前元素的class
數(shù)量。
classList
對(duì)象有下列方法。
add()
:增加一個(gè) class。remove()
:移除一個(gè) class。contains()
:檢查當(dāng)前元素是否包含某個(gè) class。toggle()
:將某個(gè) class 移入或移出當(dāng)前元素。item()
:返回指定索引位置的 class。toString()
:將 class 的列表轉(zhuǎn)為字符串。var div = document.getElementById('myDiv');
div.classList.add('myCssClass');
div.classList.add('foo', 'bar');
div.classList.remove('myCssClass');
div.classList.toggle('myCssClass'); // 如果 myCssClass 不存在就加入,否則移除
div.classList.contains('myCssClass'); // 返回 true 或者 false
div.classList.item(0); // 返回第一個(gè) Class
div.classList.toString();
下面比較一下,className
和classList
在添加和刪除某個(gè) class 時(shí)的寫(xiě)法。
var foo = document.getElementById('foo');
// 添加class
foo.className += 'bold';
foo.classList.add('bold');
// 刪除class
foo.classList.remove('bold');
foo.className = foo.className.replace(/^bold$/, '');
toggle
方法可以接受一個(gè)布爾值,作為第二個(gè)參數(shù)。如果為true
,則添加該屬性;如果為false
,則去除該屬性。
el.classList.toggle('abc', boolValue);
// 等同于
if (boolValue) {
el.classList.add('abc');
} else {
el.classList.remove('abc');
}
網(wǎng)頁(yè)元素可以自定義data-
屬性,用來(lái)添加數(shù)據(jù)。
<div data-timestamp="1522907809292"></div>
上面代碼中,<div>
元素有一個(gè)自定義的data-timestamp
屬性,用來(lái)為該元素添加一個(gè)時(shí)間戳。
Element.dataset
屬性返回一個(gè)對(duì)象,可以從這個(gè)對(duì)象讀寫(xiě)data-
屬性。
// <article
// id="foo"
// data-columns="3"
// data-index-number="12314"
// data-parent="cars">
// ...
// </article>
var article = document.getElementById('foo');
article.dataset.columns // "3"
article.dataset.indexNumber // "12314"
article.dataset.parent // "cars"
注意,dataset
上面的各個(gè)屬性返回都是字符串。
HTML 代碼中,data-
屬性的屬性名,只能包含英文字母、數(shù)字、連詞線(-
)、點(diǎn)(.
)、冒號(hào)(:
)和下劃線(_
)。它們轉(zhuǎn)成 JavaScript 對(duì)應(yīng)的dataset
屬性名,規(guī)則如下。
data-
會(huì)省略。因此,data-abc-def
對(duì)應(yīng)dataset.abcDef
,data-abc-1
對(duì)應(yīng)dataset["abc-1"]
。
除了使用dataset
讀寫(xiě)data-
屬性,也可以使用Element.getAttribute()
和Element.setAttribute()
,通過(guò)完整的屬性名讀寫(xiě)這些屬性。
var mydiv = document.getElementById('mydiv');
mydiv.dataset.foo = 'bar';
mydiv.getAttribute('data-foo') // "bar"
Element.innerHTML
屬性返回一個(gè)字符串,等同于該元素包含的所有 HTML 代碼。該屬性可讀寫(xiě),常用來(lái)設(shè)置某個(gè)節(jié)點(diǎn)的內(nèi)容。它能改寫(xiě)所有元素節(jié)點(diǎn)的內(nèi)容,包括<HTML>
和<body>
元素。
如果將innerHTML
屬性設(shè)為空,等于刪除所有它包含的所有節(jié)點(diǎn)。
el.innerHTML = '';
上面代碼等于將el
節(jié)點(diǎn)變成了一個(gè)空節(jié)點(diǎn),el
原來(lái)包含的節(jié)點(diǎn)被全部刪除。
注意,讀取屬性值的時(shí)候,如果文本節(jié)點(diǎn)包含&
、小于號(hào)(<
)和大于號(hào)(>
),innerHTML
屬性會(huì)將它們轉(zhuǎn)為實(shí)體形式&
、<
、>
。如果想得到原文,建議使用element.textContent
屬性。
// HTML代碼如下 <p id="para"> 5 > 3 </p>
document.getElementById('para').innerHTML
// 5 > 3
寫(xiě)入的時(shí)候,如果插入的文本包含 HTML 標(biāo)簽,會(huì)被解析成為節(jié)點(diǎn)對(duì)象插入 DOM。注意,如果文本之中含有<script>
標(biāo)簽,雖然可以生成script
節(jié)點(diǎn),但是插入的代碼不會(huì)執(zhí)行。
var name = "<script>alert('haha')</script>";
el.innerHTML = name;
上面代碼將腳本插入內(nèi)容,腳本并不會(huì)執(zhí)行。但是,innerHTML
還是有安全風(fēng)險(xiǎn)的。
var name = "<img src=x onerror=alert(1)>";
el.innerHTML = name;
上面代碼中,alert
方法是會(huì)執(zhí)行的。因此為了安全考慮,如果插入的是文本,最好用textContent
屬性代替innerHTML
。
Element.outerHTML
屬性返回一個(gè)字符串,表示當(dāng)前元素節(jié)點(diǎn)的所有 HTML 代碼,包括該元素本身和所有子元素。
// HTML 代碼如下
// <div id="d"><p>Hello</p></div>
var d = document.getElementById('d');
d.outerHTML
// '<div id="d"><p>Hello</p></div>'
outerHTML
屬性是可讀寫(xiě)的,對(duì)它進(jìn)行賦值,等于替換掉當(dāng)前元素。
// HTML 代碼如下
// <div id="container"><div id="d">Hello</div></div>
var container = document.getElementById('container');
var d = document.getElementById('d');
container.firstChild.nodeName // "DIV"
d.nodeName // "DIV"
d.outerHTML = '<p>Hello</p>';
container.firstChild.nodeName // "P"
d.nodeName // "DIV"
上面代碼中,變量d
代表子節(jié)點(diǎn),它的outerHTML
屬性重新賦值以后,內(nèi)層的div
元素就不存在了,被p
元素替換了。但是,變量d
依然指向原來(lái)的div
元素,這表示被替換的DIV
元素還存在于內(nèi)存中。
注意,如果一個(gè)節(jié)點(diǎn)沒(méi)有父節(jié)點(diǎn),設(shè)置outerHTML
屬性會(huì)報(bào)錯(cuò)。
var div = document.createElement('div');
div.outerHTML = '<p>test</p>';
// DOMException: This element has no parent node.
上面代碼中,div
元素沒(méi)有父節(jié)點(diǎn),設(shè)置outerHTML
屬性會(huì)報(bào)錯(cuò)。
Element.clientHeight
屬性返回一個(gè)整數(shù)值,表示元素節(jié)點(diǎn)的 CSS 高度(單位像素),只對(duì)塊級(jí)元素生效,對(duì)于行內(nèi)元素返回0
。如果塊級(jí)元素沒(méi)有設(shè)置 CSS 高度,則返回實(shí)際高度。
除了元素本身的高度,它還包括padding
部分,但是不包括border
、margin
。如果有水平滾動(dòng)條,還要減去水平滾動(dòng)條的高度。注意,這個(gè)值始終是整數(shù),如果是小數(shù)會(huì)被四舍五入。
Element.clientWidth
屬性返回元素節(jié)點(diǎn)的 CSS 寬度,同樣只對(duì)塊級(jí)元素有效,也是只包括元素本身的寬度和padding
,如果有垂直滾動(dòng)條,還要減去垂直滾動(dòng)條的寬度。
document.documentElement
的clientHeight
屬性,返回當(dāng)前視口的高度(即瀏覽器窗口的高度),等同于window.innerHeight
屬性減去水平滾動(dòng)條的高度(如果有的話)。document.body
的高度則是網(wǎng)頁(yè)的實(shí)際高度。一般來(lái)說(shuō),document.body.clientHeight
大于document.documentElement.clientHeight
。
// 視口高度
document.documentElement.clientHeight
// 網(wǎng)頁(yè)總高度
document.body.clientHeight
Element.clientLeft
屬性等于元素節(jié)點(diǎn)左邊框(left border)的寬度(單位像素),不包括左側(cè)的padding
和margin
。如果沒(méi)有設(shè)置左邊框,或者是行內(nèi)元素(display: inline
),該屬性返回0
。該屬性總是返回整數(shù)值,如果是小數(shù),會(huì)四舍五入。
Element.clientTop
屬性等于網(wǎng)頁(yè)元素頂部邊框的寬度(單位像素),其他特點(diǎn)都與clientLeft
相同。
Element.scrollHeight
屬性返回一個(gè)整數(shù)值(小數(shù)會(huì)四舍五入),表示當(dāng)前元素的總高度(單位像素),包括溢出容器、當(dāng)前不可見(jiàn)的部分。它包括padding
,但是不包括border
、margin
以及水平滾動(dòng)條的高度(如果有水平滾動(dòng)條的話),還包括偽元素(::before
或::after
)的高度。
Element.scrollWidth
屬性表示當(dāng)前元素的總寬度(單位像素),其他地方都與scrollHeight
屬性類(lèi)似。這兩個(gè)屬性只讀。
整張網(wǎng)頁(yè)的總高度可以從document.documentElement
或document.body
上讀取。
// 返回網(wǎng)頁(yè)的總高度
document.documentElement.scrollHeight
document.body.scrollHeight
注意,如果元素節(jié)點(diǎn)的內(nèi)容出現(xiàn)溢出,即使溢出的內(nèi)容是隱藏的,scrollHeight
屬性仍然返回元素的總高度。
// HTML 代碼如下
// <div id="myDiv" style="height: 200px; overflow: hidden;">...<div>
document.getElementById('myDiv').scrollHeight // 356
上面代碼中,即使myDiv
元素的 CSS 高度只有200像素,且溢出部分不可見(jiàn),但是scrollHeight
仍然會(huì)返回該元素的原始高度。
Element.scrollLeft
屬性表示當(dāng)前元素的水平滾動(dòng)條向右側(cè)滾動(dòng)的像素?cái)?shù)量,Element.scrollTop
屬性表示當(dāng)前元素的垂直滾動(dòng)條向下滾動(dòng)的像素?cái)?shù)量。對(duì)于那些沒(méi)有滾動(dòng)條的網(wǎng)頁(yè)元素,這兩個(gè)屬性總是等于0。
如果要查看整張網(wǎng)頁(yè)的水平的和垂直的滾動(dòng)距離,要從document.documentElement
元素上讀取。
document.documentElement.scrollLeft
document.documentElement.scrollTop
這兩個(gè)屬性都可讀寫(xiě),設(shè)置該屬性的值,會(huì)導(dǎo)致瀏覽器將當(dāng)前元素自動(dòng)滾動(dòng)到相應(yīng)的位置。
Element.offsetParent
屬性返回最靠近當(dāng)前元素的、并且 CSS 的position
屬性不等于static
的上層元素。
<div style="position: absolute;">
<p>
<span>Hello</span>
</p>
</div>
上面代碼中,span
元素的offsetParent
屬性就是div
元素。
該屬性主要用于確定子元素位置偏移的計(jì)算基準(zhǔn),Element.offsetTop
和Element.offsetLeft
就是offsetParent
元素計(jì)算的。
如果該元素是不可見(jiàn)的(display
屬性為none
),或者位置是固定的(position
屬性為fixed
),則offsetParent
屬性返回null
。
<div style="position: absolute;">
<p>
<span style="display: none;">Hello</span>
</p>
</div>
上面代碼中,span
元素的offsetParent
屬性是null
。
如果某個(gè)元素的所有上層節(jié)點(diǎn)的position
屬性都是static
,則Element.offsetParent
屬性指向<body>
元素。
Element.offsetHeight
屬性返回一個(gè)整數(shù),表示元素的 CSS 垂直高度(單位像素),包括元素本身的高度、padding 和 border,以及水平滾動(dòng)條的高度(如果存在滾動(dòng)條)。
Element.offsetWidth
屬性表示元素的 CSS 水平寬度(單位像素),其他都與Element.offsetHeight
一致。
這兩個(gè)屬性都是只讀屬性,只比Element.clientHeight
和Element.clientWidth
多了邊框的高度或?qū)挾?。如果元素?CSS 設(shè)為不可見(jiàn)(比如display: none;
),則返回0
。
Element.offsetLeft
返回當(dāng)前元素左上角相對(duì)于Element.offsetParent
節(jié)點(diǎn)的水平位移,Element.offsetTop
返回垂直位移,單位為像素。通常,這兩個(gè)值是指相對(duì)于父節(jié)點(diǎn)的位移。
下面的代碼可以算出元素左上角相對(duì)于整張網(wǎng)頁(yè)的坐標(biāo)。
function getElementPosition(e) {
var x = 0;
var y = 0;
while (e !== null) {
x += e.offsetLeft;
y += e.offsetTop;
e = e.offsetParent;
}
return {x: x, y: y};
}
每個(gè)元素節(jié)點(diǎn)都有style
用來(lái)讀寫(xiě)該元素的行內(nèi)樣式信息,具體介紹參見(jiàn)《CSS 操作》一章。
Element.children
屬性返回一個(gè)類(lèi)似數(shù)組的對(duì)象(HTMLCollection
實(shí)例),包括當(dāng)前元素節(jié)點(diǎn)的所有子元素。如果當(dāng)前元素沒(méi)有子元素,則返回的對(duì)象包含零個(gè)成員。
if (para.children.length) {
var children = para.children;
for (var i = 0; i < children.length; i++) {
// ...
}
}
上面代碼遍歷了para
元素的所有子元素。
這個(gè)屬性與Node.childNodes
屬性的區(qū)別是,它只包括元素類(lèi)型的子節(jié)點(diǎn),不包括其他類(lèi)型的子節(jié)點(diǎn)。
Element.childElementCount
屬性返回當(dāng)前元素節(jié)點(diǎn)包含的子元素節(jié)點(diǎn)的個(gè)數(shù),與Element.children.length
的值相同。
Element.firstElementChild
屬性返回當(dāng)前元素的第一個(gè)元素子節(jié)點(diǎn),Element.lastElementChild
返回最后一個(gè)元素子節(jié)點(diǎn)。
如果沒(méi)有元素子節(jié)點(diǎn),這兩個(gè)屬性返回null
。
Element.nextElementSibling
屬性返回當(dāng)前元素節(jié)點(diǎn)的后一個(gè)同級(jí)元素節(jié)點(diǎn),如果沒(méi)有則返回null
。
// HTML 代碼如下
// <div id="div-01">Here is div-01</div>
// <div id="div-02">Here is div-02</div>
var el = document.getElementById('div-01');
el.nextElementSibling
// <div id="div-02">Here is div-02</div>
Element.previousElementSibling
屬性返回當(dāng)前元素節(jié)點(diǎn)的前一個(gè)同級(jí)元素節(jié)點(diǎn),如果沒(méi)有則返回null
。
元素節(jié)點(diǎn)提供六個(gè)方法,用來(lái)操作屬性。
getAttribute()
:讀取某個(gè)屬性的值getAttributeNames()
:返回當(dāng)前元素的所有屬性名setAttribute()
:寫(xiě)入屬性值hasAttribute()
:某個(gè)屬性是否存在hasAttributes()
:當(dāng)前元素是否有屬性removeAttribute()
:刪除屬性這些方法的介紹請(qǐng)看《屬性的操作》一章。
Element.querySelector
方法接受 CSS 選擇器作為參數(shù),返回父元素的第一個(gè)匹配的子元素。如果沒(méi)有找到匹配的子元素,就返回null
。
var content = document.getElementById('content');
var el = content.querySelector('p');
上面代碼返回content
節(jié)點(diǎn)的第一個(gè)p
元素。
Element.querySelector
方法可以接受任何復(fù)雜的 CSS 選擇器。
document.body.querySelector("style[type='text/css'], style:not([type])");
注意,這個(gè)方法無(wú)法選中偽元素。
它可以接受多個(gè)選擇器,它們之間使用逗號(hào)分隔。
element.querySelector('div, p')
上面代碼返回element
的第一個(gè)div
或p
子元素。
需要注意的是,瀏覽器執(zhí)行querySelector
方法時(shí),是先在全局范圍內(nèi)搜索給定的 CSS 選擇器,然后過(guò)濾出哪些屬于當(dāng)前元素的子元素。因此,會(huì)有一些違反直覺(jué)的結(jié)果,下面是一段 HTML 代碼。
<div>
<blockquote id="outer">
<p>Hello</p>
<div id="inner">
<p>World</p>
</div>
</blockquote>
</div>
那么,像下面這樣查詢的話,實(shí)際上返回的是第一個(gè)p
元素,而不是第二個(gè)。
var outer = document.getElementById('outer');
outer.querySelector('div p')
// <p>Hello</p>
Element.querySelectorAll
方法接受 CSS 選擇器作為參數(shù),返回一個(gè)NodeList
實(shí)例,包含所有匹配的子元素。
var el = document.querySelector('#test');
var matches = el.querySelectorAll('div.highlighted > p');
該方法的執(zhí)行機(jī)制與querySelector
方法相同,也是先在全局范圍內(nèi)查找,再過(guò)濾出當(dāng)前元素的子元素。因此,選擇器實(shí)際上針對(duì)整個(gè)文檔的。
它也可以接受多個(gè) CSS 選擇器,它們之間使用逗號(hào)分隔。如果選擇器里面有偽元素的選擇器,則總是返回一個(gè)空的NodeList
實(shí)例。
Element.getElementsByClassName
方法返回一個(gè)HTMLCollection
實(shí)例,成員是當(dāng)前元素節(jié)點(diǎn)的所有具有指定 class 的子元素節(jié)點(diǎn)。該方法與document.getElementsByClassName
方法的用法類(lèi)似,只是搜索范圍不是整個(gè)文檔,而是當(dāng)前元素節(jié)點(diǎn)。
element.getElementsByClassName('red test');
注意,該方法的參數(shù)大小寫(xiě)敏感。
由于HTMLCollection
實(shí)例是一個(gè)活的集合,document
對(duì)象的任何變化會(huì)立刻反應(yīng)到實(shí)例,下面的代碼不會(huì)生效。
// HTML 代碼如下
// <div id="example">
// <p class="foo"></p>
// <p class="foo"></p>
// </div>
var element = document.getElementById('example');
var matches = element.getElementsByClassName('foo');
for (var i = 0; i< matches.length; i++) {
matches[i].classList.remove('foo');
matches.item(i).classList.add('bar');
}
// 執(zhí)行后,HTML 代碼如下
// <div id="example">
// <p></p>
// <p class="foo bar"></p>
// </div>
上面代碼中,matches
集合的第一個(gè)成員,一旦被拿掉 class 里面的foo
,就會(huì)立刻從matches
里面消失,導(dǎo)致出現(xiàn)上面的結(jié)果。
Element.getElementsByTagName()
方法返回一個(gè)HTMLCollection
實(shí)例,成員是當(dāng)前節(jié)點(diǎn)的所有匹配指定標(biāo)簽名的子元素節(jié)點(diǎn)。該方法與document.getElementsByClassName()
方法的用法類(lèi)似,只是搜索范圍不是整個(gè)文檔,而是當(dāng)前元素節(jié)點(diǎn)。
var table = document.getElementById('forecast-table');
var cells = table.getElementsByTagName('td');
注意,該方法的參數(shù)是大小寫(xiě)不敏感的,因?yàn)?HTML 標(biāo)簽名也是大小寫(xiě)不敏感。
Element.closest
方法接受一個(gè) CSS 選擇器作為參數(shù),返回匹配該選擇器的、最接近當(dāng)前節(jié)點(diǎn)的一個(gè)祖先節(jié)點(diǎn)(包括當(dāng)前節(jié)點(diǎn)本身)。如果沒(méi)有任何節(jié)點(diǎn)匹配 CSS 選擇器,則返回null
。
// HTML 代碼如下
// <article>
// <div id="div-01">Here is div-01
// <div id="div-02">Here is div-02
// <div id="div-03">Here is div-03</div>
// </div>
// </div>
// </article>
var div03 = document.getElementById('div-03');
// div-03 最近的祖先節(jié)點(diǎn)
div03.closest("#div-02") // div-02
div03.closest("div div") // div-03
div03.closest("article > div") //div-01
div03.closest(":not(div)") // article
上面代碼中,由于closest
方法將當(dāng)前節(jié)點(diǎn)也考慮在內(nèi),所以第二個(gè)closest
方法返回div-03
。
Element.matches
方法返回一個(gè)布爾值,表示當(dāng)前元素是否匹配給定的 CSS 選擇器。
if (el.matches('.someClass')) {
console.log('Match!');
}
以下三個(gè)方法與Element
節(jié)點(diǎn)的事件相關(guān)。這些方法都繼承自EventTarget
接口,詳見(jiàn)相關(guān)章節(jié)。
Element.addEventListener()
:添加事件的回調(diào)函數(shù)Element.removeEventListener()
:移除事件監(jiān)聽(tīng)函數(shù)Element.dispatchEvent()
:觸發(fā)事件element.addEventListener('click', listener, false);
element.removeEventListener('click', listener, false);
var event = new Event('click');
element.dispatchEvent(event);
Element.scrollIntoView
方法滾動(dòng)當(dāng)前元素,進(jìn)入瀏覽器的可見(jiàn)區(qū)域,類(lèi)似于設(shè)置window.location.hash
的效果。
el.scrollIntoView(); // 等同于el.scrollIntoView(true)
el.scrollIntoView(false);
該方法可以接受一個(gè)布爾值作為參數(shù)。如果為true
,表示元素的頂部與當(dāng)前區(qū)域的可見(jiàn)部分的頂部對(duì)齊(前提是當(dāng)前區(qū)域可滾動(dòng));如果為false
,表示元素的底部與當(dāng)前區(qū)域的可見(jiàn)部分的尾部對(duì)齊(前提是當(dāng)前區(qū)域可滾動(dòng))。如果沒(méi)有提供該參數(shù),默認(rèn)為true
。
Element.getBoundingClientRect
方法返回一個(gè)對(duì)象,提供當(dāng)前元素節(jié)點(diǎn)的大小、位置等信息,基本上就是 CSS 盒狀模型的所有信息。
var rect = obj.getBoundingClientRect();
上面代碼中,getBoundingClientRect
方法返回的rect
對(duì)象,具有以下屬性(全部為只讀)。
x
:元素左上角相對(duì)于視口的橫坐標(biāo)y
:元素左上角相對(duì)于視口的縱坐標(biāo)height
:元素高度width
:元素寬度left
:元素左上角相對(duì)于視口的橫坐標(biāo),與x
屬性相等right
:元素右邊界相對(duì)于視口的橫坐標(biāo)(等于x + width
)top
:元素頂部相對(duì)于視口的縱坐標(biāo),與y
屬性相等bottom
:元素底部相對(duì)于視口的縱坐標(biāo)(等于y + height
)由于元素相對(duì)于視口(viewport)的位置,會(huì)隨著頁(yè)面滾動(dòng)變化,因此表示位置的四個(gè)屬性值,都不是固定不變的。如果想得到絕對(duì)位置,可以將left
屬性加上window.scrollX
,top
屬性加上window.scrollY
。
注意,getBoundingClientRect
方法的所有屬性,都把邊框(border
屬性)算作元素的一部分。也就是說(shuō),都是從邊框外緣的各個(gè)點(diǎn)來(lái)計(jì)算。因此,width
和height
包括了元素本身 + padding
+ border
。
另外,上面的這些屬性,都是繼承自原型的屬性,Object.keys
會(huì)返回一個(gè)空數(shù)組,這一點(diǎn)也需要注意。
var rect = document.body.getBoundingClientRect();
Object.keys(rect) // []
上面代碼中,rect
對(duì)象沒(méi)有自身屬性,而Object.keys
方法只返回對(duì)象自身的屬性,所以返回了一個(gè)空數(shù)組。
Element.getClientRects
方法返回一個(gè)類(lèi)似數(shù)組的對(duì)象,里面是當(dāng)前元素在頁(yè)面上形成的所有矩形(所以方法名中的Rect
用的是復(fù)數(shù))。每個(gè)矩形都有bottom
、height
、left
、right
、top
和width
六個(gè)屬性,表示它們相對(duì)于視口的四個(gè)坐標(biāo),以及本身的高度和寬度。
對(duì)于盒狀元素(比如<div>
和<p>
),該方法返回的對(duì)象中只有該元素一個(gè)成員。對(duì)于行內(nèi)元素(比如<span>
、<a>
、<em>
),該方法返回的對(duì)象有多少個(gè)成員,取決于該元素在頁(yè)面上占據(jù)多少行。這是它和Element.getBoundingClientRect()
方法的主要區(qū)別,后者對(duì)于行內(nèi)元素總是返回一個(gè)矩形。
<span id="inline">Hello World Hello World Hello World</span>
上面代碼是一個(gè)行內(nèi)元素<span>
,如果它在頁(yè)面上占據(jù)三行,getClientRects
方法返回的對(duì)象就有三個(gè)成員,如果它在頁(yè)面上占據(jù)一行,getClientRects
方法返回的對(duì)象就只有一個(gè)成員。
var el = document.getElementById('inline');
el.getClientRects().length // 3
el.getClientRects()[0].left // 8
el.getClientRects()[0].right // 113.908203125
el.getClientRects()[0].bottom // 31.200000762939453
el.getClientRects()[0].height // 23.200000762939453
el.getClientRects()[0].width // 105.908203125
這個(gè)方法主要用于判斷行內(nèi)元素是否換行,以及行內(nèi)元素的每一行的位置偏移。
注意,如果行內(nèi)元素包括換行符,那么該方法會(huì)把換行符考慮在內(nèi)。
<span id="inline">
Hello World
Hello World
Hello World
</span>
上面代碼中,<span>
節(jié)點(diǎn)內(nèi)部有三個(gè)換行符,即使 HTML 語(yǔ)言忽略換行符,將它們顯示為一行,getClientRects()
方法依然會(huì)返回三個(gè)成員。如果行寬設(shè)置得特別窄,上面的<span>
元素顯示為6行,那么就會(huì)返回六個(gè)成員。
Element.insertAdjacentElement
方法在相對(duì)于當(dāng)前元素的指定位置,插入一個(gè)新的節(jié)點(diǎn)。該方法返回被插入的節(jié)點(diǎn),如果插入失敗,返回null
。
element.insertAdjacentElement(position, element);
Element.insertAdjacentElement
方法一共可以接受兩個(gè)參數(shù),第一個(gè)參數(shù)是一個(gè)字符串,表示插入的位置,第二個(gè)參數(shù)是將要插入的節(jié)點(diǎn)。第一個(gè)參數(shù)只可以取如下的值。
beforebegin
:當(dāng)前元素之前afterbegin
:當(dāng)前元素內(nèi)部的第一個(gè)子節(jié)點(diǎn)前面beforeend
:當(dāng)前元素內(nèi)部的最后一個(gè)子節(jié)點(diǎn)后面afterend
:當(dāng)前元素之后注意,beforebegin
和afterend
這兩個(gè)值,只在當(dāng)前節(jié)點(diǎn)有父節(jié)點(diǎn)時(shí)才會(huì)生效。如果當(dāng)前節(jié)點(diǎn)是由腳本創(chuàng)建的,沒(méi)有父節(jié)點(diǎn),那么插入會(huì)失敗。
var p1 = document.createElement('p')
var p2 = document.createElement('p')
p1.insertAdjacentElement('afterend', p2) // null
上面代碼中,p1
沒(méi)有父節(jié)點(diǎn),所以插入p2
到它后面就失敗了。
如果插入的節(jié)點(diǎn)是一個(gè)文檔里現(xiàn)有的節(jié)點(diǎn),它會(huì)從原有位置刪除,放置到新的位置。
Element.insertAdjacentHTML
方法用于將一個(gè) HTML 字符串,解析生成 DOM 結(jié)構(gòu),插入相對(duì)于當(dāng)前節(jié)點(diǎn)的指定位置。
element.insertAdjacentHTML(position, text);
該方法接受兩個(gè)參數(shù),第一個(gè)是一個(gè)表示指定位置的字符串,第二個(gè)是待解析的 HTML 字符串。第一個(gè)參數(shù)只能設(shè)置下面四個(gè)值之一。
beforebegin
:當(dāng)前元素之前afterbegin
:當(dāng)前元素內(nèi)部的第一個(gè)子節(jié)點(diǎn)前面beforeend
:當(dāng)前元素內(nèi)部的最后一個(gè)子節(jié)點(diǎn)后面afterend
:當(dāng)前元素之后// HTML 代碼:<div id="one">one</div>
var d1 = document.getElementById('one');
d1.insertAdjacentHTML('afterend', '<div id="two">two</div>');
// 執(zhí)行后的 HTML 代碼:
// <div id="one">one</div><div id="two">two</div>
該方法只是在現(xiàn)有的 DOM 結(jié)構(gòu)里面插入節(jié)點(diǎn),這使得它的執(zhí)行速度比innerHTML
方法快得多。
注意,該方法不會(huì)轉(zhuǎn)義 HTML 字符串,這導(dǎo)致它不能用來(lái)插入用戶輸入的內(nèi)容,否則會(huì)有安全風(fēng)險(xiǎn)。
Element.insertAdjacentText
方法在相對(duì)于當(dāng)前節(jié)點(diǎn)的指定位置,插入一個(gè)文本節(jié)點(diǎn),用法與Element.insertAdjacentHTML
方法完全一致。
// HTML 代碼:<div id="one">one</div>
var d1 = document.getElementById('one');
d1.insertAdjacentText('afterend', 'two');
// 執(zhí)行后的 HTML 代碼:
// <div id="one">one</div>two
Element.remove
方法繼承自 ChildNode 接口,用于將當(dāng)前元素節(jié)點(diǎn)從它的父節(jié)點(diǎn)移除。
var el = document.getElementById('mydiv');
el.remove();
上面代碼將el
節(jié)點(diǎn)從 DOM 樹(shù)里面移除。
Element.focus
方法用于將當(dāng)前頁(yè)面的焦點(diǎn),轉(zhuǎn)移到指定元素上。
document.getElementById('my-span').focus();
該方法可以接受一個(gè)對(duì)象作為參數(shù)。參數(shù)對(duì)象的preventScroll
屬性是一個(gè)布爾值,指定是否將當(dāng)前元素停留在原始位置,而不是滾動(dòng)到可見(jiàn)區(qū)域。
function getFocus() {
document.getElementById('btn').focus({preventScroll:false});
}
上面代碼會(huì)讓btn
元素獲得焦點(diǎn),并滾動(dòng)到可見(jiàn)區(qū)域。
最后,從document.activeElement
屬性可以得到當(dāng)前獲得焦點(diǎn)的元素。
Element.blur
方法用于將焦點(diǎn)從當(dāng)前元素移除。
Element.click
方法用于在當(dāng)前元素上模擬一次鼠標(biāo)點(diǎn)擊,相當(dāng)于觸發(fā)了click
事件。
更多建議: