Element
對象對應(yīng)網(wǎng)頁的HTML標(biāo)簽元素。每一個HTML標(biāo)簽元素,在DOM樹上都會轉(zhuǎn)化成一個Element
節(jié)點對象(以下簡稱元素節(jié)點)。
元素節(jié)點的nodeType
屬性都是1,但是不同HTML標(biāo)簽生成的元素節(jié)點時不一樣的。JS內(nèi)部使用不同的構(gòu)造函數(shù),生成不同的Element
節(jié)點,比如<a>
標(biāo)簽的節(jié)點對象由HTMLAnchorElement()
構(gòu)造函數(shù)生成,<button>
標(biāo)簽的節(jié)點對象由HTMLButtonElement()
構(gòu)造函數(shù)生成。因此,元素節(jié)點不是一種對象,而是一組對象。
一、與元素本身特征相關(guān)的屬性
以下屬性與元素本身的特征相關(guān)。
1.1、Element.attributes
Element.attributes
屬性返回一個類似數(shù)組的對象,成員是當(dāng)前元素節(jié)點的所有屬性節(jié)點。下一節(jié)將詳細(xì)介紹。
1.2、Element.id,Element.tagName
Element.id
屬性返回指定元素的id
屬性,該屬性可讀寫。
Element.tagName
屬性返回指定元素的大寫標(biāo)簽名,與nodeName
屬性的值相等。
// HTML代碼為
// <span id="myspan">Hello</span>
var span = document.getElementById('span');
span.id // "myspan"
span.tagName // "SPAN"
1.3、Element.innerHTML
Element.innerHTML
屬性返回該元素包含的HTML代碼。該屬性可讀寫,常用來設(shè)置某個節(jié)點的內(nèi)容。
如果將該屬性設(shè)為空,等于刪除它包含的所有節(jié)點。
el.innerHTML = '';
上面代碼等于將el
節(jié)點變成了一個空節(jié)點,el
原來包含的節(jié)點被全部刪除。
注意,如果文本節(jié)點中包含&
、小于號和大于號,innerHTML
屬性會將它們轉(zhuǎn)為實體形式&
、<
、>
。
// HTML代碼如下 <p id="para"> 5 > 3 </p>
document.getElementById('para').innerHTML
// 5 > 3
由于上面這個原因,導(dǎo)致用innerHTML
插入<script>
標(biāo)簽,不會被執(zhí)行。
var name = "<script>alert('haha')</script>";
el.innerHTML = name;
上面代碼將腳本插入內(nèi)容,腳本并不會執(zhí)行。但是,innerHTML
還是有安全風(fēng)險的。
var name = "<img src=x onerror=alert(1)>";
el.innerHTML = name;
上面代碼中,alert
方法是會執(zhí)行的。因此為了安全考慮,如果插入的事文本,最好用textContent
屬性代替innerHTML
。
1.4、Element.outerHTML
Element.outerHTML
屬性返回一個字符串,內(nèi)容為指定元素節(jié)點的所有HTML代碼,包括它自身和包含的所有子元素。
// HTML代碼如下
// <div id="d"><p>Hello</p></div>
d = document.getElementById('d');
d.outerHTML
// '<div id="d"><p>Hello</p></div>'
outerHTML
屬性是可讀寫的,對它進行賦值,等于替換掉當(dāng)前元素。
// HTML代碼如下
// <div id="container"><div id="d">Hello</div></div>
container = document.getElementById('container');
d = document.getElementById("d");
container.firstChild.nodeName // "DIV"
d.nodeName // "DIV"
d.outerHTML = '<p>Hello</p>';
container.firstChild.nodeName // "P"
d.nodeName // "DIV"
上面代碼中,outerHTML
屬性重新賦值以后,內(nèi)層的div元素就不存在了,被p元素替換了。但是,變量d依然指向原來的div元素,這表示被替換的DIV元素還存在于內(nèi)存中。
1.5、Element.className,Element.classList
className
屬性用來讀寫當(dāng)前元素節(jié)點的class
屬性。它的值是一個字符串,每個class
之間用空格分割。
classList
屬性則返回一個類似數(shù)組的對象,當(dāng)前元素節(jié)點的每個class
就是這個對象的一個成員。
<div class="one two three" id="myDiv"></div>
上面這個div元素節(jié)點對象的className屬性和classList屬性,分別如下。
document.getElementById('myDiv').className
// "one two three"
document.getElementById('myDiv').classList
// {
// 0: "one"
// 1: "two"
// 2: "three"
// length: 3
// }
從上面代碼可以看出,className
屬性返回一個空格分隔的字符串,而classList
屬性指向一個類似數(shù)組的對象,該對象的length
屬性(只讀)返回當(dāng)前元素的class
數(shù)量。
classList對象有下列方法。
add():增加一個class。
remove():移除一個class。
contains():檢查當(dāng)前元素是否包含某個class。
toggle():將某個class移入或移出當(dāng)前元素。
item():返回指定索引位置的class。
toString():將class的列表轉(zhuǎn)為字符串。
myDiv.classList.add('myCssClass');
myDiv.classList.add('foo', 'bar');
myDiv.classList.remove('myCssClass');
myDiv.classList.toggle('myCssClass'); // 如果myCssClass不存在就加入,否則移除
myDiv.classList.contains('myCssClass'); // 返回 true 或者 false
myDiv.classList.item(0); // 返回第一個Class
myDiv.classList.toString();
下面比較一下,className和classList在添加和刪除某個類時的寫法。
// 添加class
document.getElementById('foo').className += 'bold';
document.getElementById('foo').classList.add('bold');
// 刪除class
document.getElementById('foo').classList.remove('bold');
document.getElementById('foo').className =
document.getElementById('foo').className.replace(/^bold$/, '');
toggle
方法可以接受一個布爾值,作為第二個參數(shù)。如果為true
,則添加該屬性;如果為false
,則去除該屬性。
el.classList.toggle('abc', boolValue);
// 等同于
if (boolValue){
el.classList.add('abc');
} else {
el.classList.remove('abc');
}
二、盒狀模型相關(guān)屬性
2.1、Element.clientHeight,Element.clientWidth
Element.clientHeight
屬性返回元素節(jié)點可見部分的高度,Element.clientWidth
屬性返回元素節(jié)點可見部分的寬度。所謂可見部分,指的是不包括溢出的大小,只返回該元素在容器中占據(jù)的大小,對于有滾動條的元素來說,它們等于滾動條圍起來的區(qū)域大小。這兩個屬性的值包括Padding、但不包括滾動條、邊框和Margin,單位為像素。這兩個屬性可以計算得到,等于元素的CSS高度(或?qū)挾龋┘由螩SS的padding,減去滾動條(如果存在)。
對于整張網(wǎng)頁來說,當(dāng)前可見高度(即視口高度)要從document.documentElement
對象(即<html>
節(jié)點)上獲取,等同于window.innerHeight
屬性減去水平滾動條的高度。沒有滾動條時,這兩個值是相等的;有滾動條時,前者小于后者。
2.2、Element.clientLeft,Element.clientTop
2.3、Element.scrollHeight,Element.scrollWidth
2.4、Element.scrollLeft,Element.scrollTop
2.5、Element.offsetHeight,Element.offsetWidth
2.6、Element.offsetLeft,Element.offsetTop
2.7、Element.style
每個元素節(jié)點都有style用來讀寫該元素的行內(nèi)樣式信息。
2.8、總結(jié)
三、返回元素節(jié)點相關(guān)節(jié)點的屬性
以下屬性返回元素節(jié)點的相關(guān)節(jié)點。
3.1、Element.children,Element.childElementCount
Element.children
屬性返回一個HTMLCollection
對象,包括當(dāng)前元素節(jié)點的所有子節(jié)點。它是一個類似數(shù)組的動態(tài)對象(實時反映網(wǎng)頁元素的變化)。如果當(dāng)前元素沒有子元素,則返回的對象包含零個成員。
// para是一個p元素節(jié)點
if (para.children.length) {
var children = para.children;
for (var i = 0; i < children.length; i++) {
// ...
}
}
這個屬性與Node.childNodes
屬性的區(qū)別是,它只包括HTML元素類型的子節(jié)點,不包括其他類型的子節(jié)點。
Element.childElementCount
屬性返回當(dāng)前元素節(jié)點包含的子HTML元素節(jié)點的個數(shù),與Element.children.length
的值相同。注意,該屬性只計算HTML元素類型的子節(jié)點。
3.2、Element.firstElementChild,Element.lastElementChild
Element.firstElementChild
屬性返回第一個HTML元素類型的子節(jié)點,Element.lastElementChild
返回最后一個HTML元素類型的子節(jié)點。
如果沒有HTML類型的子節(jié)點,這兩個屬性返回null
。
3.3、Element.nextElementSibling,Element.previousElementSibling
Element.nextElementSibling
屬性返回當(dāng)前HTML元素節(jié)點的后一個同級HTML元素節(jié)點,如果沒有則返回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)前HTML元素節(jié)點的前一個同級HTML元素節(jié)點,如果沒有則返回null
。
3.4、Element.offsetParent
Element.offsetParent
屬性返回當(dāng)前HTML元素的最靠近的、并且CSS的position
屬性不等于static
的父元素。如果某個元素的所有上層節(jié)點都將position
屬性設(shè)為static
,則Element.offsetParent
屬性指向<body>
元素。
該屬性主要用于確定子元素的位置偏移,是Element.offsetTop
和Element.offsetLeft
的計算基準(zhǔn)。
四、操作元素屬性相關(guān)的方法
元素節(jié)點提供以下四個方法,用來操作HTML標(biāo)簽的屬性。
- Element.getAttribute():讀取指定屬性
- Element.setAttribute():設(shè)置指定屬性
- Element.hasAttribute():返回一個布爾值,表示當(dāng)前元素節(jié)點是否有指定的屬性
- Element.removeAttribute():移除指定屬性
五、查找相關(guān)的方法
以下四個方法用來查找與當(dāng)前元素節(jié)點相關(guān)的節(jié)點。這四個方法也部署在document
對象上,用法完全一致。
- Element.querySelector()
- Element.querySelectorAll()
- Element.getElementByTagName()
- Element.getElementByClassName()
上面四個方法只返回Element
子節(jié)點,因此可以采用鏈?zhǔn)綄懛ā?/p>
document
.getElementById('header')
.getElementsByClassName('a')
5.1、Element.querySelector()
Element.querySelector
方法接受CSS選擇器作為參數(shù),返回父元素的第一個匹配的子元素。
var content = document.getElementById('content');
var el = content.querySelector('p');
上面代碼返回content
節(jié)點的第一個p
元素。
需要注意的是,瀏覽器執(zhí)行querySelector
方法時,是先在全局范圍內(nèi)搜索給定的CSS選擇器,然后過濾出哪些屬于當(dāng)前元素的子元素。因此,會有一些違反直覺的結(jié)果。
<div>
<blockquote id="outer">
<p>Hello</p>
<div id="inner">
<p>World</p>
</div>
</blockquote>
</div>
那么,下面代碼實際上會返回第一個p元素,而不是第二個。
var outer = document.getElementById('outer');
outer.querySelector('div p')
// <p>Hello</p>
5.2、Element.querySelectorAll()
Element.querySelectorAll
方法接受CSS選擇器作為參數(shù),返回一個NodeList
對象,包含所有匹配的子元素。
該方法的執(zhí)行機制與querySelector
相同,也是先在全局范圍內(nèi)查找,再過濾出當(dāng)前元素的子元素。因此,選擇器實際上針對整個文檔的。
5.3、Element.getElementsByTagName()
Element.getElementsByTagName
方法返回一個HTMLCollection
對象,成員是當(dāng)前元素節(jié)點的所有匹配指定標(biāo)簽名的子元素。該方法與document.getElementsByTagName
方法的用法類似,只是搜索范圍不是整個文檔,而是當(dāng)前元素節(jié)點。
同樣的,該方法的參數(shù)大小寫不敏感。
5.4、Element.getElementsByClassName()
Element.getElementsByClassName
方法返回一個HTMLCollection
對象,成員是當(dāng)前元素節(jié)點的所有匹配指定class的子元素。該方法與document.getElementsByClassName
方法的用法類似,只是搜索范圍不是整個文檔,而是當(dāng)前元素節(jié)點。
該方法的參數(shù)大小寫敏感。
5.5、Element.closest()
Element.closest
方法返回當(dāng)前元素節(jié)點的最接近的父元素(或者當(dāng)前節(jié)點本身),條件是必須匹配給定的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>
//JS代碼
var el = document.getElementById('div-03');
el.closest("#div-02") // div-02
el.closest("div div") // div-03
el.closest("article > div") //div-01
el.closest(":not(div)") // article
上面代碼中,由于closet
方法將當(dāng)前元素節(jié)點也考慮在內(nèi),所以第二個closet
方法返回div-03
。
5.6、Element.match()
Element.match
方法返回一個布爾值,表示當(dāng)前元素是否匹配給定的CSS選擇器。
六、事件相關(guān)的方法
以下三個方法與Element節(jié)點的事件相關(guān)。這些方法都繼承自EventTarget接口。
- Element.addEventListener():添加事件的回調(diào)函數(shù)
- Element.removeEventListener():移除事件監(jiān)聽函數(shù)
- Element.dispatchEvent():觸發(fā)事件
element.addEventListener('click', listener, false);
element.removeEventListener('click', listener, false);
var event = new Event('click');
element.dispatchEvent(event);
七、其他方法
7.1、Element.scrollIntoView()
7.2、Element.getBoundingClientRect()
7.3、Element.getClientRects()
7.4、Element.insertAdjacentHTML()
7.5、Element.remove()
Element.remove
方法用于將當(dāng)前元素節(jié)點從DOM樹刪除。
var el = document.getElementById('div-01');
el.remove();
7.6、Element.focus()
Element.focus
方法用于將當(dāng)前頁面的焦點,轉(zhuǎn)移到指定元素上。
document.getElementById('my-span').focus();