Element對象

Element對象對應(yīng)網(wǎng)頁的 HTML 元素绪颖。每一個 HTML 元素浪谴,在 DOM 樹上都會轉(zhuǎn)化成一個Element節(jié)點對象(以下簡稱元素節(jié)點)瘪匿。

元素節(jié)點的nodeType屬性都是1萨赁。

var p = document.querySelector('p');
p.nodeName // "P"
p.nodeType // 1

Element對象繼承了Node接口,因此Node的屬性和方法在Element對象都存在芥挣。此外膳汪,不同的 HTML 元素對應(yīng)的元素節(jié)點是不一樣的,瀏覽器使用不同的構(gòu)造函數(shù)九秀,生成不同的元素節(jié)點,比如<a>元素的節(jié)點對象由HTMLAnchorElement構(gòu)造函數(shù)生成粘我,<button>元素的節(jié)點對象由HTMLButtonElement構(gòu)造函數(shù)生成鼓蜒。因此痹换,元素節(jié)點不是一種對象,而是一組對象都弹,這些對象除了繼承Element的屬性和方法娇豫,還有各自構(gòu)造函數(shù)的屬性和方法。

1.實例屬性

1.1 元素特性的相關(guān)屬性

(1)Element.id

Element.id屬性返回指定元素的id屬性畅厢,該屬性可讀寫冯痢。

// HTML 代碼為 <p id="foo">
var p = document.querySelector('p');
p.id // "foo"

注意,id屬性的值是大小寫敏感框杜,即瀏覽器能正確識別<p id="foo"><p id="FOO">這兩個元素的id屬性浦楣,但是最好不要這樣命名。

(2)Element.tagName

Element.tagName屬性返回指定元素的大寫標簽名咪辱,與nodeName屬性的值相等振劳。

// HTML代碼為
// <span id="myspan">Hello</span>
var span = document.getElementById('myspan');
span.id // "myspan"
span.tagName // "SPAN"

(3)Element.dir

Element.dir屬性用于讀寫當前元素的文字方向,可能是從左到右("ltr")油狂,也可能是從右到左("rtl")历恐。

(4)Element.accessKey

Element.accessKey屬性用于讀寫分配給當前元素的快捷鍵。

// HTML 代碼如下
// <button accesskey="h" id="btn">點擊</button>
var btn = document.getElementById('btn');
btn.accessKey // "h"

上面代碼中专筷,btn元素的快捷鍵是h弱贼,按下Alt + h就能將焦點轉(zhuǎn)移到它上面。

(5)Element.draggable

Element.draggable屬性返回一個布爾值磷蛹,表示當前元素是否可拖動吮旅。該屬性可讀寫。

(6)Element.lang

Element.lang屬性返回當前元素的語言設(shè)置弦聂。該屬性可讀寫鸟辅。

// HTML 代碼如下
// <html lang="en">
document.documentElement.lang // "en"

(7)Element.tabIndex

Element.tabIndex屬性返回一個整數(shù),表示當前元素在 Tab 鍵遍歷時的順序莺葫。該屬性可讀寫匪凉。

tabIndex屬性值如果是負值(通常是-1),則 Tab 鍵不會遍歷到該元素捺檬。如果是正整數(shù)再层,則按照順序,從小到大遍歷堡纬。如果兩個元素的tabIndex屬性的正整數(shù)值相同聂受,則按照出現(xiàn)的順序遍歷。遍歷完所有tabIndex為正整數(shù)的元素以后烤镐,再遍歷所有tabIndex等于0蛋济、或者屬性值是非法值、或者沒有tabIndex屬性的元素炮叶,順序為它們在網(wǎng)頁中出現(xiàn)的順序碗旅。

(8)Element.title

Element.title屬性用來讀寫當前元素的 HTML 屬性title渡处。該屬性通常用來指定,鼠標懸浮時彈出的文字提示框祟辟。

1.2 元素狀態(tài)的相關(guān)屬性

(1)Element.hidden

Element.hidden屬性返回一個布爾值医瘫,表示當前元素的hidden屬性,用來控制當前元素是否可見旧困。該屬性可讀寫醇份。

var btn = document.getElementById('btn');
var mydiv = document.getElementById('mydiv');

btn.addEventListener('click', function () {
  mydiv.hidden = !mydiv.hidden;
}, false);

注意,該屬性與 CSS 設(shè)置是互相獨立的吼具。CSS 對這個元素可見性的設(shè)置僚纷,Element.hidden并不能反映出來。也就是說馍悟,這個屬性并不能用來判斷當前元素的實際可見性畔濒。

CSS 的設(shè)置高于Element.hidden。如果 CSS 指定了該元素不可見(display: none)或可見(display: hidden)锣咒,那么Element.hidden并不能改變該元素實際的可見性侵状。換言之,這個屬性只在 CSS 沒有明確設(shè)定當前元素的可見性時才有效毅整。

(2)Element.contentEditable趣兄,Element.isContentEditable

HTML 元素可以設(shè)置contentEditable屬性,使得元素的內(nèi)容可以編輯悼嫉。

<div contenteditable>123</div>

上面代碼中艇潭,<div>元素有contenteditable屬性,因此用戶可以在網(wǎng)頁上編輯這個區(qū)塊的內(nèi)容戏蔑。

Element.contentEditable屬性返回一個字符串蹋凝,表示是否設(shè)置了contenteditable屬性,有三種可能的值总棵。該屬性可寫鳍寂。

"true":元素內(nèi)容可編輯

"false":元素內(nèi)容不可編輯

"inherit":元素是否可編輯,繼承了父元素的設(shè)置

Element.isContentEditable屬性返回一個布爾值情龄,同樣表示是否設(shè)置了contenteditable屬性迄汛。該屬性只讀。

1.3 Element.attributes

Element.attributes屬性返回一個類似數(shù)組的對象骤视,成員是當前元素節(jié)點的所有屬性節(jié)點鞍爱,詳見《Attr 對象》一章。

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元素的所有屬性专酗。

1.4 Element.className睹逃,Element.classList

className屬性用來讀寫當前元素節(jié)點的class屬性。它的值是一個字符串祷肯,每個class之間用空格分割唯卖。

classList屬性返回一個類似數(shù)組的對象粱玲,當前元素節(jié)點的每個class就是這個對象的一個成員。

// 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屬性返回一個空格分隔的字符串,而classList屬性指向一個類似數(shù)組的對象允青,該對象的length屬性(只讀)返回當前元素的class數(shù)量橄碾。

classList對象有下列方法。

  • add():增加一個 class颠锉。
  • remove():移除一個 class法牲。
  • contains():檢查當前元素是否包含某個 class。
  • toggle():將某個 class 移入或移出當前元素琼掠。
  • 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); // 返回第一個 Class
div.classList.toString();

下面比較一下悼瓮,classNameclassList在添加和刪除某個 class 時的寫法。

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方法可以接受一個布爾值艰猬,作為第二個參數(shù)横堡。如果為true,則添加該屬性冠桃;如果為false命贴,則去除該屬性。

el.classList.toggle('abc', boolValue);

// 等同于
if (boolValue) {
  el.classList.add('abc');
} else {
  el.classList.remove('abc');
}

1.5 Element.dataset

網(wǎng)頁元素可以自定義data-屬性食听,用來添加數(shù)據(jù)胸蛛。

<div data-timestamp="1522907809292"></div>

上面代碼中,<div>元素有一個自定義的data-timestamp屬性樱报,用來為該元素添加一個時間戳葬项。

Element.dataset屬性返回一個對象,可以從這個對象讀寫data-屬性肃弟。

// <article
//   id="foo"
//   data-columns="3"
//   data-index-number="12314"
//   data-parent="cars">
//   ...
// </article>
var article = document.getElementById('foo');
foo.dataset.columns // "3"
foo.dataset.indexNumber // "12314"
foo.dataset.parent // "cars"

注意玷室,dataset上面的各個屬性返回都是字符串。

HTML 代碼中笤受,data-屬性的屬性名穷缤,只能包含英文字母、數(shù)字箩兽、連詞線(-)津肛、點(.)、冒號(:)和下劃線(_)汗贫。它們轉(zhuǎn)成 JavaScript 對應(yīng)的dataset屬性名身坐,規(guī)則如下秸脱。

  • 開頭的data-會省略。
  • 如果連詞線后面跟了一個英文字母部蛇,那么連詞線會取消摊唇,該字母變成大寫。
  • 其他字符不變涯鲁。

因此巷查,data-abc-def對應(yīng)dataset.abcDefdata-abc-1對應(yīng)dataset["abc-1"]抹腿。

除了使用dataset讀寫data-屬性岛请,也可以使用Element.getAttribute()Element.setAttribute(),通過完整的屬性名讀寫這些屬性警绩。

var mydiv = document.getElementById('mydiv');

mydiv.dataset.foo = 'bar';
mydiv.getAttribute('data-foo') // "bar"

1.6 Element.innerHTML

Element.innerHTML屬性返回一個字符串崇败,等同于該元素包含的所有 HTML 代碼。該屬性可讀寫肩祥,常用來設(shè)置某個節(jié)點的內(nèi)容后室。它能改寫所有元素節(jié)點的內(nèi)容,包括<HTML><body>元素搭幻。

如果將innerHTML屬性設(shè)為空咧擂,等于刪除所有它包含的所有節(jié)點。

el.innerHTML = '';

上面代碼等于將el節(jié)點變成了一個空節(jié)點檀蹋,el原來包含的節(jié)點被全部刪除松申。

注意,讀取屬性值的時候俯逾,如果文本節(jié)點包含&贸桶、小于號(<)和大于號(>),innerHTML屬性會將它們轉(zhuǎn)為實體形式&amp;桌肴、&lt;皇筛、&gt;。如果想得到原文坠七,建議使用element.textContent屬性水醋。

// HTML代碼如下 <p id="para"> 5 > 3 </p>
document.getElementById('para').innerHTML
// 5 &gt; 3

寫入的時候,如果插入的文本包含 HTML 標簽彪置,會被解析成為節(jié)點對象插入 DOM拄踪。注意,如果文本之中含有<script>標簽拳魁,雖然可以生成script節(jié)點惶桐,但是插入的代碼不會執(zhí)行。

var name = "<script>alert('haha')</script>";
el.innerHTML = name;

上面代碼將腳本插入內(nèi)容,腳本并不會執(zhí)行姚糊。但是贿衍,innerHTML還是有安全風險的。

var name = "<img src=x onerror=alert(1)>";
el.innerHTML = name;

上面代碼中救恨,alert方法是會執(zhí)行的贸辈。因此為了安全考慮,如果插入的是文本忿薇,最好用textContent屬性代替innerHTML裙椭。

1.7 Element.outerHTML

Element.outerHTML屬性返回一個字符串,表示當前元素節(jié)點的所有 HTML 代碼署浩,包括該元素本身和所有子元素。

// HTML 代碼如下
// <div id="d"><p>Hello</p></div>
var d = document.getElementById('d');
d.outerHTML
// '<div id="d"><p>Hello</p></div>'

outerHTML屬性是可讀寫的扫尺,對它進行賦值筋栋,等于替換掉當前元素。

// 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é)點弊攘,它的outerHTML屬性重新賦值以后,內(nèi)層的div元素就不存在了姑曙,被p元素替換了襟交。但是,變量d依然指向原來的div元素伤靠,這表示被替換的DIV元素還存在于內(nèi)存中捣域。

注意,

如果一個節(jié)點沒有父節(jié)點宴合,設(shè)置outerHTML屬性會報錯焕梅。

var div = document.createElement('div');
div.outerHTML = '<p>test</p>';
// DOMException: This element has no parent node.

上面代碼中,div元素沒有父節(jié)點卦洽,設(shè)置outerHTML屬性會報錯贞言。

1.8 Element.clientHeight,Element.clientWidth

(1)Element.clientHeight

返回一個整數(shù)值阀蒂,表示元素節(jié)點的 CSS 高度(單位像素)该窗,只對塊級元素生效,對于行內(nèi)元素返回0蚤霞。如果塊級元素沒有設(shè)置 CSS 高度酗失,則返回實際高度

除了元素本身的高度争便,它還包括padding部分级零,但是不包括bordermargin

如果有水平滾動條奏纪,還要減去水平滾動條的高度鉴嗤。注意,這個值始終是整數(shù)序调,如果是小數(shù)會被四舍五入醉锅。

(2)Element.clientWidth

返回元素節(jié)點的 CSS 寬度,同樣只對塊級元素有效发绢,也是只包括元素本身的寬度和padding硬耍,如果有垂直滾動條,還要減去垂直滾動條的寬度边酒。

(3)document.documentElement.clientHeight

返回當前視口的高度(即瀏覽器窗口的高度)经柴,等同于window.innerHeight屬性減去水平滾動條的高度(如果有的話)。

(4)document.body

高度則是網(wǎng)頁的實際高度墩朦。

一般來說坯认,document.body.clientHeight大于document.documentElement.clientHeight

// 視口高度
document.documentElement.clientHeight

// 網(wǎng)頁總高度
document.body.clientHeight

1.9 Element.clientLeft氓涣,Element.clientTop

Element.clientLeft屬性等于元素節(jié)點左邊框(left border)的寬度(單位像素)牛哺,不包括左側(cè)的paddingmargin。如果沒有設(shè)置左邊框劳吠,或者是行內(nèi)元素(display: inline)引润,該屬性返回0。該屬性總是返回整數(shù)值痒玩,如果是小數(shù)淳附,會四舍五入。

Element.clientTop屬性等于網(wǎng)頁元素頂部邊框的寬度(單位像素)凰荚,其他特點都與clientTop相同燃观。

1.10 Element.scrollHeight,Element.scrollWidth

Element.scrollHeight屬性返回一個整數(shù)值(小數(shù)會四舍五入)便瑟,表示當前元素的總高度(單位像素)缆毁,包括溢出容器、當前不可見的部分到涂。它包括padding脊框,但是不包括bordermargin以及水平滾動條的高度(如果有水平滾動條的話)践啄,還包括偽元素(::before::after)的高度浇雹。

Element.scrollWidth屬性表示當前元素的總寬度(單位像素),其他地方都與scrollHeight屬性類似屿讽。這兩個屬性只讀昭灵。

整張網(wǎng)頁的總高度可以從document.documentElementdocument.body上讀取吠裆。

// 返回網(wǎng)頁的總高度
document.documentElement.scrollHeight
document.body.scrollHeight

注意,如果元素節(jié)點的內(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像素祝旷,且溢出部分不可見,但是scrollHeight仍然會返回該元素的原始高度嘶窄。

1.11 Element.scrollLeft怀跛,Element.scrollTop

Element.scrollLeft屬性表示當前元素的水平滾動條向右側(cè)滾動的像素數(shù)量,Element.scrollTop屬性表示當前元素的垂直滾動條向下滾動的像素數(shù)量柄冲。對于那些沒有滾動條的網(wǎng)頁元素吻谋,這兩個屬性總是等于0。

如果要查看整張網(wǎng)頁的水平的和垂直的滾動距離现横,要從document.documentElement元素上讀取滨溉。

document.documentElement.scrollLeft
document.documentElement.scrollTop

這兩個屬性都可讀寫,設(shè)置該屬性的值长赞,會導致瀏覽器將當前元素自動滾動到相應(yīng)的位置。

1.12 Element.offsetParent

Element.offsetParent屬性返回最靠近當前元素的闽撤、并且 CSS 的position屬性不等于static的上層元素得哆。

<div style="position: absolute;">
  <p>
    <span>Hello</span>
  </p>
</div>

上面代碼中,span元素的offsetParent屬性就是div元素哟旗。

該屬性主要用于確定子元素位置偏移的計算基準贩据,Element.offsetTopElement.offsetLeft就是offsetParent元素計算的。

如果該元素是不可見的(display屬性為none)闸餐,或者位置是固定的(position屬性為fixed)饱亮,則offsetParent屬性返回null

<div style="position: absolute;">
  <p>
    <span style="display: none;">Hello</span>
  </p>
</div>

上面代碼中舍沙,span元素的offsetParent屬性是null近上。

如果某個元素的所有上層節(jié)點的position屬性都是static,則Element.offsetParent屬性指向<body>元素拂铡。

1.13 Element.offsetHeight壹无,Element.offsetWidth

Element.offsetHeight屬性返回一個整數(shù),表示元素的 CSS 垂直高度(單位像素)感帅,包括元素本身的高度斗锭、padding 和 border,以及水平滾動條的高度(如果存在滾動條)失球。

Element.offsetWidth屬性表示元素的 CSS 水平寬度(單位像素)岖是,其他都與Element.offsetHeight一致。

這兩個屬性都是只讀屬性,只比Element.clientHeightElement.clientWidth多了邊框的高度或?qū)挾炔虺拧H绻氐?CSS 設(shè)為不可見(比如display: none;)烈疚,則返回0

1.14 Element.offsetLeft前硫,Element.offsetTop

Element.offsetLeft返回當前元素左上角相對于Element.offsetParent節(jié)點的水平位移胞得,Element.offsetTop返回垂直位移,單位為像素屹电。通常阶剑,這兩個值是指相對于父節(jié)點的位移。

下面的代碼可以算出元素左上角相對于整張網(wǎng)頁的坐標危号。

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};
}

1.15 Element.style

每個元素節(jié)點都有style用來讀寫該元素的行內(nèi)樣式信息牧愁,具體介紹參見《CSS 操作》一章。

1.16 Element.children外莲,Element.childElementCount

Element.children屬性返回一個類似數(shù)組的對象(HTMLCollection實例)猪半,包括當前元素節(jié)點的所有子元素。如果當前元素沒有子元素偷线,則返回的對象包含零個成員磨确。

if (para.children.length) {
  var children = para.children;
    for (var i = 0; i < children.length; i++) {
      // ...
    }
}

上面代碼遍歷了para元素的所有子元素。

這個屬性與Node.childNodes屬性的區(qū)別是声邦,它只包括元素類型的子節(jié)點乏奥,不包括其他類型的子節(jié)點。

Element.childElementCount屬性返回當前元素節(jié)點包含的子元素節(jié)點的個數(shù)亥曹,與Element.children.length的值相同邓了。

1.17 Element.firstElementChild,Element.lastElementChild

Element.firstElementChild屬性返回當前元素的第一個元素子節(jié)點媳瞪,Element.lastElementChild返回最后一個元素子節(jié)點骗炉。

如果沒有元素子節(jié)點,這兩個屬性返回null蛇受。

1.18 Element.nextElementSibling句葵,Element.previousElementSibling

Element.nextElementSibling屬性返回當前元素節(jié)點的后一個同級元素節(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屬性返回當前元素節(jié)點的前一個同級元素節(jié)點笼呆,如果沒有則返回null

2.實例方法

2.1 屬性相關(guān)方法

以下方法用來操作當前節(jié)點的屬性旨别。

(1)Element.getAttribute()

Element.getAttribute方法接受一個字符串作為參數(shù)诗赌,返回同名屬性的值。如果沒有該屬性秸弛,則返回null铭若。

var mydiv = document.getElementById('mydiv');
var id = mydiv.getAttribute('id');

上面代碼讀取mydivid的值洪碳。

(2)Element.getAttributeNames()

Element.getAttributeNames()返回一個數(shù)組,成員是當前元素的所有屬性的名字叼屠。如果當前元素沒有任何屬性瞳腌,則返回一個空數(shù)組。使用Element.attributes屬性镜雨,也可以拿到同樣的結(jié)果嫂侍,唯一的區(qū)別是它返回的是類似數(shù)組的對象。

var mydiv = document.getElementById('mydiv');

mydiv.getAttributeNames().forEach(function (key) {
  var value = mydiv.getAttribute(key);
  console.log(key, value);
})

上面代碼用于遍歷某個節(jié)點的所有屬性荚坞。

(3)Element.setAttribute()

Element.setAttribute方法用于為當前節(jié)點設(shè)置屬性挑宠。如果屬性已經(jīng)存在,將更新屬性值颓影,否則將添加該屬性各淀。該方法沒有返回值。

// HTML 代碼為
// <button>Hello World</button>
var b = document.querySelector('button');
b.setAttribute('name', 'myButton');
b.setAttribute('disabled', true);

上面代碼中诡挂,button元素的name屬性被設(shè)成myButton碎浇,disabled屬性被設(shè)成true

上面代碼中璃俗,button元素的name屬性被設(shè)成myButton奴璃,disabled屬性被設(shè)成true

這里有兩個地方需要注意城豁,首先溺健,屬性值總是字符串,其他類型的值會自動轉(zhuǎn)成字符串钮蛛,比如布爾值true就會變成字符串true;其次剖膳,上例的disable屬性是一個布爾屬性魏颓,對于<button>元素來說,這個屬性不需要屬性值吱晒,只要設(shè)置了就總是會生效甸饱,因此setAttribute方法里面可以將disabled屬性設(shè)成任意值。

(4)Element.hasAttribute()

Element.hasAttribute方法返回一個布爾值仑濒,表示當前元素節(jié)點是否有指定的屬性叹话。

var foo = document.getElementById('foo');
foo.hasAttribute('bar') // false

(5)Element.hasAttributes()

Element.hasAttributes方法返回一個布爾值,表示當前元素是否有屬性墩瞳,如果沒有任何屬性驼壶,就返回false,否則返回true喉酌。

var foo = document.getElementById('foo');
foo.hasAttributes() // true

(6)Element.removeAttribute()

Element.removeAttribute方法移除指定屬性热凹。該方法沒有返回值泵喘。

document.getElementById('div1').removeAttribute('id')

2.2 Element.querySelector()

Element.querySelector方法接受 CSS 選擇器作為參數(shù),返回父元素的第一個匹配的子元素般妙。如果沒有找到匹配的子元素纪铺,就返回null

var content = document.getElementById('content');
var el = content.querySelector('p');

上面代碼返回content節(jié)點的第一個p元素碟渺。

Element.querySelector方法可以接受任何復雜的 CSS 選擇器鲜锚。

document.body.querySelector("style[type='text/css'], style:not([type])");

注意,這個方法無法選中偽元素苫拍。

它可以接受多個選擇器芜繁,它們之間使用逗號分隔。

element.querySelector('div, p')

上面代碼返回element的第一個divp子元素怯疤。

需要注意的是浆洗,瀏覽器執(zhí)行querySelector方法時,是先在全局范圍內(nèi)搜索給定的 CSS 選擇器集峦,然后過濾出哪些屬于當前元素的子元素伏社。因此,會有一些違反直覺的結(jié)果塔淤,下面是一段 HTML 代碼摘昌。

<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>

2.3 Element.querySelectorAll()

Element.querySelectorAll方法接受 CSS 選擇器作為參數(shù)备恤,返回一個NodeList實例稿饰,包含所有匹配的子元素。

var el = document.querySelector('#test');
var matches = el.querySelectorAll('div.highlighted > p');

該方法的執(zhí)行機制與querySelector方法相同露泊,也是先在全局范圍內(nèi)查找喉镰,再過濾出當前元素的子元素。因此惭笑,選擇器實際上針對整個文檔的侣姆。

它也可以接受多個 CSS 選擇器命浴,它們之間使用逗號分隔逐抑。如果選擇器里面有偽元素的選擇器藕帜,則總是返回一個空的NodeList實例搓侄。

2.4 Element.getElementsByClassName()

Element.getElementsByClassName方法返回一個HTMLCollection實例蝎困,成員是當前元素節(jié)點的所有具有指定 class 的子元素節(jié)點择卦。該方法與document.getElementsByClassName方法的用法類似事富,只是搜索范圍不是整個文檔砰逻,而是當前元素節(jié)點畜眨。

element.getElementsByClassName('red test');

注意弯囊,該方法的參數(shù)大小寫敏感痰哨。

由于HTMLCollection實例是一個活的集合,document對象的任何變化會立刻反應(yīng)到實例匾嘱,下面的代碼不會生效斤斧。

// 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集合的第一個成員撬讽,一旦被拿掉 class 里面的foo,就會立刻從matches里面消失悬垃,導致出現(xiàn)上面的結(jié)果游昼。

2.5 Element.getElementsByTagName()

Element.getElementsByTagName方法返回一個HTMLCollection實例,成員是當前節(jié)點的所有匹配指定標簽名的子元素節(jié)點尝蠕。該方法與document.getElementsByClassName方法的用法類似烘豌,只是搜索范圍不是整個文檔,而是當前元素節(jié)點看彼。

var table = document.getElementById('forecast-table');
var cells = table.getElementsByTagName('td');

注意廊佩,該方法的參數(shù)是大小寫不敏感的。

2.6 Element.closest()

Element.closest方法接受一個 CSS 選擇器作為參數(shù)靖榕,返回匹配該選擇器的标锄、最接近當前節(jié)點的一個祖先節(jié)點(包括當前節(jié)點本身)。如果沒有任何節(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>

var div03 = document.getElementById('div-03');

// div-03 最近的祖先節(jié)點
div03.closest("#div-02") // div-02
div03.closest("div div") // div-03
div03.closest("article > div") //div-01
div03.closest(":not(div)") // article

上面代碼中,由于closest方法將當前節(jié)點也考慮在內(nèi)星压,所以第二個closest方法返回div-03践剂。

2.7 Element.matches()

Element.matches方法返回一個布爾值,表示當前元素是否匹配給定的 CSS 選擇器娜膘。

if (el.matches('.someClass')) {
  console.log('Match!');
}

2.8 事件相關(guān)方法

以下三個方法與Element節(jié)點的事件相關(guān)舷手。這些方法都繼承自EventTarget接口,詳見相關(guān)章節(jié)劲绪。

  • 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);

2.9 Element.scrollIntoView()

Element.scrollIntoView方法滾動當前元素,進入瀏覽器的可見區(qū)域盆赤,類似于設(shè)置window.location.hash的效果贾富。

el.scrollIntoView(); // 等同于el.scrollIntoView(true)
el.scrollIntoView(false);

該方法可以接受一個布爾值作為參數(shù)。如果為true牺六,表示元素的頂部與當前區(qū)域的可見部分的頂部對齊(前提是當前區(qū)域可滾動)颤枪;如果為false,表示元素的底部與當前區(qū)域的可見部分的尾部對齊(前提是當前區(qū)域可滾動)淑际。如果沒有提供該參數(shù)畏纲,默認為true扇住。

2.10 Element.getBoundingClientRect()

Element.getBoundingClientRect方法返回一個對象,提供當前元素節(jié)點的大小盗胀、位置等信息艘蹋,基本上就是 CSS 盒狀模型的所有信息。

var rect = obj.getBoundingClientRect();

上面代碼中票灰,getBoundingClientRect方法返回的rect對象女阀,具有以下屬性(全部為只讀)。

  • x:元素左上角相對于視口的橫坐標
  • y:元素左上角相對于視口的縱坐標
  • height:元素高度
  • width:元素寬度
  • left:元素左上角相對于視口的橫坐標屑迂,與x屬性相等
  • right:元素右邊界相對于視口的橫坐標(等于x + width
  • top:元素頂部相對于視口的縱坐標浸策,與y屬性相等
  • bottom:元素底部相對于視口的縱坐標(等于y + height

由于元素相對于視口(viewport)的位置,會隨著頁面滾動變化惹盼,因此表示位置的四個屬性值庸汗,都不是固定不變的。如果想得到絕對位置手报,可以將left屬性加上window.scrollX蚯舱,top屬性加上window.scrollY

注意昧诱,getBoundingClientRect方法的所有屬性晓淀,都把邊框(border屬性)算作元素的一部分。也就是說盏档,都是從邊框外緣的各個點來計算凶掰。因此,widthheight包括了元素本身 + padding + border蜈亩。

另外懦窘,上面的這些屬性,都是繼承自原型的屬性稚配,Object.keys會返回一個空數(shù)組畅涂,這一點也需要注意。

var rect = document.body.getBoundingClientRect();
Object.keys(rect) // []

上面代碼中道川,rect對象沒有自身屬性午衰,而Object.keys方法只返回對象自身的屬性,所以返回了一個空數(shù)組冒萄。

2.11 Element.getClientRects()

Element.getClientRects方法返回一個類似數(shù)組的對象臊岸,里面是當前元素在頁面上形成的所有矩形(所以方法名中的Rect用的是復數(shù))。每個矩形都有bottom尊流、height帅戒、leftright崖技、topwidth六個屬性逻住,表示它們相對于視口的四個坐標钟哥,以及本身的高度和寬度。

對于盒狀元素(比如<div><p>)瞎访,該方法返回的對象中只有該元素一個成員腻贰。對于行內(nèi)元素(比如<span><a>装诡、<em>)银受,該方法返回的對象有多少個成員,取決于該元素在頁面上占據(jù)多少行鸦采。這是它和Element.getBoundingClientRect()方法的主要區(qū)別宾巍,后者對于行內(nèi)元素總是返回一個矩形。

<span id="inline">Hello World Hello World Hello World</span>

上面代碼是一個行內(nèi)元素<span>渔伯,如果它在頁面上占據(jù)三行顶霞,getClientRects方法返回的對象就有三個成員,如果它在頁面上占據(jù)一行锣吼,getClientRects方法返回的對象就只有一個成員选浑。

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

這個方法主要用于判斷行內(nèi)元素是否換行,以及行內(nèi)元素的每一行的位置偏移玄叠。

注意古徒,如果行內(nèi)元素包括換行符,那么該方法會把換行符考慮在內(nèi)读恃。

<span id="inline">
  Hello World
  Hello World
  Hello World
</span>

上面代碼中隧膘,<span>節(jié)點內(nèi)部有三個換行符,即使 HTML 語言忽略換行符寺惫,將它們顯示為一行疹吃,getClientRects()方法依然會返回三個成員。如果行寬設(shè)置得特別窄西雀,上面的<span>元素顯示為6行萨驶,那么就會返回六個成員。

2.12 Element.insertAdjacentElement()

Element.insertAdjacentElement方法在相對于當前元素的指定位置艇肴,插入一個新的節(jié)點腔呜。該方法返回被插入的節(jié)點,如果插入失敗再悼,返回null核畴。

element.insertAdjacentElement(position, element);

Element.insertAdjacentElement方法一共可以接受兩個參數(shù),第一個參數(shù)是一個字符串帮哈,表示插入的位置,第二個參數(shù)是將要插入的節(jié)點锰镀。第一個參數(shù)只可以取如下的值娘侍。

  • beforebegin:當前元素之前
  • afterbegin:當前元素內(nèi)部的第一個子節(jié)點前面
  • beforeend:當前元素內(nèi)部的最后一個子節(jié)點后面
  • afterend:當前元素之后

注意咖刃,beforebeginafterend這兩個值,只在當前節(jié)點有父節(jié)點時才會生效憾筏。如果當前節(jié)點是由腳本創(chuàng)建的嚎杨,沒有父節(jié)點,那么插入會失敗氧腰。

var p1 = document.createElement('p')
var p2 = document.createElement('p')
p1.insertAdjacentElement('afterend', p2) // null

上面代碼中枫浙,p1沒有父節(jié)點,所以插入p2到它后面就失敗了古拴。

如果插入的節(jié)點是一個文檔里現(xiàn)有的節(jié)點箩帚,它會從原有位置刪除,放置到新的位置黄痪。

2.13 Element.insertAdjacentHTML()紧帕,Element.insertAdjacentText()

Element.insertAdjacentHTML方法用于將一個 HTML 字符串,解析生成 DOM 結(jié)構(gòu)桅打,插入相對于當前節(jié)點的指定位置是嗜。

element.insertAdjacentHTML(position, text);

該方法接受兩個參數(shù),第一個是一個表示指定位置的字符串挺尾,第二個是待解析的 HTML 字符串鹅搪。第一個參數(shù)只能設(shè)置下面四個值之一。

  • beforebegin:當前元素之前
  • afterbegin:當前元素內(nèi)部的第一個子節(jié)點前面
  • beforeend:當前元素內(nèi)部的最后一個子節(jié)點后面
  • afterend:當前元素之后
// 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é)點遭铺,這使得它的執(zhí)行速度比innerHTML方法快得多丽柿。

注意,該方法不會轉(zhuǎn)義 HTML 字符串掂僵,這導致它不能用來插入用戶輸入的內(nèi)容航厚,否則會有安全風險。

Element.insertAdjacentText方法在相對于當前節(jié)點的指定位置锰蓬,插入一個文本節(jié)點幔睬,用法與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

2.14 Element.remove()

Element.remove方法繼承自 ChildNode 接口芹扭,用于將當前元素節(jié)點從它的父節(jié)點移除麻顶。

var el = document.getElementById('mydiv');
el.remove();

上面代碼將el節(jié)點從 DOM 樹里面移除。

2.15 Element.focus()舱卡,Element.blur()

Element.focus方法用于將當前頁面的焦點辅肾,轉(zhuǎn)移到指定元素上。

document.getElementById('my-span').focus();

該方法可以接受一個對象作為參數(shù)轮锥。參數(shù)對象的preventScroll屬性是一個布爾值矫钓,指定是否將當前元素停留在原始位置,而不是滾動到可見區(qū)域。

function getFocus() {
  document.getElementById('btn').focus({preventScroll:false});
}

上面代碼會讓btn元素獲得焦點新娜,并滾動到可見區(qū)域赵辕。

最后,從document.activeElement屬性可以得到當前獲得焦點的元素概龄。

Element.blur方法用于將焦點從當前元素移除还惠。

2.16 Element.click()

Element.click方法用于在當前元素上模擬一次鼠標點擊,相當于觸發(fā)了click事件私杜。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蚕键,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子衰粹,更是在濱河造成了極大的恐慌锣光,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件寄猩,死亡現(xiàn)場離奇詭異嫉晶,居然都是意外死亡,警方通過查閱死者的電腦和手機田篇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門替废,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人泊柬,你說我怎么就攤上這事椎镣。” “怎么了兽赁?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵状答,是天一觀的道長。 經(jīng)常有香客問我刀崖,道長惊科,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任亮钦,我火速辦了婚禮馆截,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蜂莉。我一直安慰自己蜡娶,他們只是感情好,可當我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布映穗。 她就那樣靜靜地躺著窖张,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蚁滋。 梳的紋絲不亂的頭發(fā)上宿接,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天赘淮,我揣著相機與錄音,去河邊找鬼睦霎。 笑死拥知,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的碎赢。 我是一名探鬼主播,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼速梗,長吁一口氣:“原來是場噩夢啊……” “哼肮塞!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起姻锁,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤枕赵,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后位隶,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拷窜,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年涧黄,在試婚紗的時候發(fā)現(xiàn)自己被綠了篮昧。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡笋妥,死狀恐怖懊昨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情春宣,我是刑警寧澤酵颁,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站月帝,受9級特大地震影響躏惋,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜嚷辅,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一簿姨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧潦蝇,春花似錦款熬、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至则酝,卻和暖如春殉簸,著一層夾襖步出監(jiān)牢的瞬間闰集,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工般卑, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留武鲁,地道東北人。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓蝠检,卻偏偏與公主長得像沐鼠,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子叹谁,可洞房花燭夜當晚...
    茶點故事閱讀 44,960評論 2 355