DOM模型(三)—— Element節(jié)點

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.offsetTopElement.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();
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,345評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,494評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,283評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,953評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,714評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,410評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,940評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,776評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,210評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,654評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 47,958評論 2 373

推薦閱讀更多精彩內(nèi)容