JavaScript常用的API

1 什么是DOM

文檔對(duì)象模型 (DOM) 是HTML和XML文檔的編程接口帅戒。它提供了對(duì)文檔的結(jié)構(gòu)化的表述玛歌,并定義了一種方式可以使從程序中對(duì)該結(jié)構(gòu)進(jìn)行訪問(wèn)昧港,從而改變文檔的結(jié)構(gòu)擎椰,樣式和內(nèi)容支子。
文檔對(duì)象模型 (DOM) 是對(duì)HTML文件的另一種展示,通俗地說(shuō)达舒,一個(gè)HTML 文件值朋,我們可以用編輯器以代碼的形式展示它,也可以用瀏覽器以頁(yè)面的形式展示它巩搏,同一份文件通過(guò)不同的展示方式昨登,就有了不一樣的表現(xiàn)形式。而DOM 將文檔解析為一個(gè)由節(jié)點(diǎn)和對(duì)象(包含屬性和方法的對(duì)象)組成的結(jié)構(gòu)集合贯底。簡(jiǎn)言之丰辣,它會(huì)將web頁(yè)面和腳本或程序語(yǔ)言連接起來(lái)撒强,我們可以使用腳本或者程序語(yǔ)言通過(guò)DOM 來(lái)改變或者控制web頁(yè)面。

2 如何訪問(wèn)DOM

我們可以通過(guò)JavaScript 來(lái)調(diào)用documentwindow元素的API來(lái)操作文檔或者獲取文檔的信息笙什。

3 Node

Node 是一個(gè)接口飘哨,有許多接口都從Node 繼承方法和屬性:
Document, Element, CharacterData (which Text, Comment, and CDATASection inherit), ProcessingInstruction, DocumentFragment, DocumentType, Notation, Entity, EntityReference敛纲。
Node 有一個(gè)nodeType的屬性表示Node 的類型氧猬,是一個(gè)整數(shù)揍庄,不同的值代表不同的節(jié)點(diǎn)類型泌类。具體如下表所示:

節(jié)點(diǎn)類型常量

常量 描述
Node.ELEMENT_NODE 1 一個(gè)元素節(jié)點(diǎn)裁奇,例如 <p><div>
Node.TEXT_NODE 3 Element 或者 Attr 中實(shí)際的文字
Node.PROCESSING_INSTRUCTION_NODE 7 一個(gè)用于XML文檔的 ProcessingInstruction 仑荐,例如 <?xml-stylesheet ... ?> 聲明
Node.COMMENT_NODE 8 一個(gè) Comment 節(jié)點(diǎn)
Node.DOCUMENT_NODE 9 一個(gè) Document 節(jié)點(diǎn)
Node.DOCUMENT_TYPE_NODE 10 描述文檔類型的 DocumentType 節(jié)點(diǎn)延窜。例如 <!DOCTYPE html> 就是用于 HTML5 的
Node.DOCUMENT_FRAGMENT_NODE 11 一個(gè) DocumentFragment 節(jié)點(diǎn)

已棄用的節(jié)點(diǎn)類型常量

常量 描述
Node.ATTRIBUTE_NODE 2 元素的耦合屬性书聚。在DOM4 規(guī)范里Node 接口將不再實(shí)現(xiàn)這個(gè)元素屬性
Node.CDATA_SECTION_NODE 4 一個(gè)CDATASection愁憔。在DOM4 規(guī)范里被移除
Node.ENTITY_REFERENCE_NODE 5 一個(gè)XML 實(shí)體引用節(jié)點(diǎn)腕扶。在DOM4 規(guī)范里被移除
Node.ENTITY_NODE 6 一個(gè)XML <!ENTITY ...>節(jié)點(diǎn)。在DOM4 規(guī)范中被移除
Node.NOTATION_NODE 12 一個(gè)XML <!NOTATION ...>節(jié)點(diǎn)吨掌。在DOM4 規(guī)范里被移除

假設(shè)我們要判斷一個(gè)Node 是不是一個(gè)元素蕉毯,通過(guò)查表可知元素nodeType屬性值為1,代碼可以這么寫(xiě):

if(X.nodeType === 1){
  console.log('X 是一個(gè)元素');
}

在Node 類型中思犁,比較常用的就是element代虾,textcomment激蹲,document棉磨,document_fragment這幾種類型。

3.1 Element

Element提供了對(duì)元素標(biāo)簽名学辱,子節(jié)點(diǎn)和特性的訪問(wèn)乘瓤,我們常用HTML元素比如divspan策泣,a等標(biāo)簽就是element中的一種衙傀。Element有下面幾條特性:
(1)nodeType為1
(2)nodeName為元素標(biāo)簽名,tagName也是返回標(biāo)簽名
(3)nodeValue為null
(4)parentNode可能是Document或Element
(5)子節(jié)點(diǎn)可能是Element萨咕,Text统抬,Comment,Processing_Instruction危队,CDATASection或EntityReference

3.2 Text

Text表示文本節(jié)點(diǎn)聪建,它包含的是純文本內(nèi)容,不能包含html代碼茫陆,但可以包含轉(zhuǎn)義后的html代碼金麸。Text有下面的特性:
(1)nodeType為3
(2)nodeName為#text
(3)nodeValue為文本內(nèi)容
(4)parentNode是一個(gè)Element
(5)沒(méi)有子節(jié)點(diǎn)

3.3 Comment

Comment表示HTML文檔中的注釋,它有下面的幾種特征:
(1)nodeType為8
(2)nodeName為#comment
(3)nodeValue為注釋的內(nèi)容
(4)parentNode可能是Document或Element
(5)沒(méi)有子節(jié)點(diǎn)

3.4 Document

Document表示文檔簿盅,在瀏覽器中挥下,document對(duì)象是HTMLDocument的一個(gè)實(shí)例揍魂,表示整個(gè)頁(yè)面,它同時(shí)也是window對(duì)象的一個(gè)屬性棚瘟。Document有下面的特性:
(1)nodeType為9
(2)nodeName為#document
(3)nodeValue為null
(4)parentNode為null
(5)子節(jié)點(diǎn)可能是一個(gè)DocumentType或Element

3.5 DocumentFragment

DocumentFragment是所有節(jié)點(diǎn)中唯一一個(gè)沒(méi)有對(duì)應(yīng)標(biāo)記的類型愉烙,它表示一種輕量級(jí)的文檔,可能當(dāng)作一個(gè)臨時(shí)的倉(cāng)庫(kù)用來(lái)保存可能會(huì)添加到文檔中的節(jié)點(diǎn)解取。DocumentFragment有下面的特性:
(1)nodeType為11
(2)nodeName為#document-fragment
(3)nodeValue為null
(4)parentNode為null

4 節(jié)點(diǎn)創(chuàng)建型API

用如其名步责,這類API是用來(lái)創(chuàng)建節(jié)點(diǎn)的

4.1 createElement

createElement通過(guò)傳入指定的一個(gè)標(biāo)簽名來(lái)創(chuàng)建一個(gè)元素,如果傳入的標(biāo)簽名是一個(gè)未知的禀苦,則會(huì)創(chuàng)建一個(gè)自定義的標(biāo)簽蔓肯,注意:IE8以下瀏覽器不支持自定義標(biāo)簽。

語(yǔ)法

  let element = document.createElement(tagName);

使用createElement要注意:通過(guò)createElement創(chuàng)建的元素并不屬于HTML文檔振乏,它只是創(chuàng)建出來(lái)蔗包,并未添加到HTML文檔中,要調(diào)用appendChildinsertBefore等方法將其添加到HTML文檔樹(shù)中慧邮。

例子:

  let elem = document.createElement("div");
  elem.id = 'test';
  elem.style = 'color: red';
  elem.innerHTML = '我是新創(chuàng)建的節(jié)點(diǎn)';
  document.body.appendChild(elem);

運(yùn)行結(jié)果為:


image

4.2 createTextNode

createTextNode用來(lái)創(chuàng)建一個(gè)文本節(jié)點(diǎn)

語(yǔ)法

  var text = document.createTextNode(data);

createTextNode接收一個(gè)參數(shù)调限,這個(gè)參數(shù)就是文本節(jié)點(diǎn)中的文本,和createElement一樣误澳,創(chuàng)建后的文本節(jié)點(diǎn)也只是獨(dú)立的一個(gè)節(jié)點(diǎn)耻矮,同樣需要appendChild將其添加到HTML文檔樹(shù)中

例子:

  var node = document.createTextNode("我是文本節(jié)點(diǎn)");
  document.body.appendChild(node);

運(yùn)行結(jié)果為:


image

4.3 cloneNode

cloneNode返回調(diào)用該方法的節(jié)點(diǎn)的一個(gè)副本

語(yǔ)法

  var dupNode = node.cloneNode(deep);

node 將要被克隆的節(jié)點(diǎn)
dupNode 克隆生成的副本節(jié)點(diǎn)
deep(可選)是否采用深度克隆,如果為true,則該節(jié)點(diǎn)的所有后代節(jié)點(diǎn)也都會(huì)被克隆,如果為false,則只克隆該節(jié)點(diǎn)本身.

這里有幾點(diǎn)要注意:
(1)和createElement一樣,cloneNode創(chuàng)建的節(jié)點(diǎn)只是游離有HTML文檔外的節(jié)點(diǎn)忆谓,要調(diào)用appendChild方法才能添加到文檔樹(shù)中
(2)如果復(fù)制的元素有id裆装,則其副本同樣會(huì)包含該id,由于id具有唯一性倡缠,所以在復(fù)制節(jié)點(diǎn)后必須要修改其id
(3)調(diào)用接收的deep參數(shù)最好傳入哨免,如果不傳入該參數(shù),不同瀏覽器對(duì)其默認(rèn)值的處理可能不同

注意
如果被復(fù)制的節(jié)點(diǎn)綁定了事件昙沦,則副本也會(huì)跟著綁定該事件嗎琢唾?這里要分情況討論:
(1)如果是通過(guò)addEventListener或者比如onclick進(jìn)行綁定事件,則副本節(jié)點(diǎn)不會(huì)綁定該事件
(2)如果是內(nèi)聯(lián)方式綁定比如:<div onclick="showParent()"></div>盾饮,這樣的話采桃,副本節(jié)點(diǎn)同樣會(huì)觸發(fā)事件。

例子:

<body>
  <div id="parent">
    我是父元素的文本
    <br/>
    <span>
        我是子元素
    </span>
  </div>
  <button id="btnCopy">復(fù)制</button>
</body>
<script>
  var parent = document.getElementById("parent");
  document.getElementById("btnCopy").onclick = function(){
    var parent2 = parent.cloneNode(true);
    parent2.id = "parent2";
    document.body.appendChild(parent2);
  }
</script>

運(yùn)行結(jié)果為:


image

4.4 createDocumentFragment

DocumentFragments 是DOM節(jié)點(diǎn)丐谋。它們不是主DOM樹(shù)的一部分芍碧。通常的用例是創(chuàng)建文檔片段,將元素附加到文檔片段号俐,然后將文檔片段附加到DOM樹(shù)。在DOM樹(shù)中定庵,文檔片段被其所有的子元素所代替吏饿。
因?yàn)槲臋n片段存在于內(nèi)存中踪危,并不在DOM樹(shù)中,所以將子元素插入到文檔片段時(shí)不會(huì)引起頁(yè)面回流(reflow)(對(duì)元素位置和幾何上的計(jì)算)猪落。因此贞远,使用文檔片段document fragments 通常會(huì)起到優(yōu)化性能的作用。

語(yǔ)法

  let fragment = document.createDocumentFragment();

例子:

<body>
  <ul id="ul"></ul>
</body>
<script>
  (function()
  {
    var start = Date.now();
    var str = '', li;
    var ul = document.getElementById('ul');
    var fragment = document.createDocumentFragment();
    for(var i=0; i<1000; i++)
    {
        li = document.createElement('li');
        li.textContent = '第'+(i+1)+'個(gè)子節(jié)點(diǎn)';
        fragment.appendChild(li);
    }
    ul.appendChild(fragment);
  })();
</script>

運(yùn)行結(jié)果為:


image

4.5 節(jié)點(diǎn)創(chuàng)建型API總結(jié)

節(jié)點(diǎn)創(chuàng)建型API主要包括createElement笨忌,createTextNode蓝仲,cloneNodecreateDocumentFragment四個(gè)方法,需要注意下面幾點(diǎn):
(1)它們創(chuàng)建的節(jié)點(diǎn)只是一個(gè)孤立的節(jié)點(diǎn)官疲,要通過(guò)appendChild添加到文檔中
(2)cloneNode要注意如果被復(fù)制的節(jié)點(diǎn)是否包含子節(jié)點(diǎn)以及事件綁定等問(wèn)題
(3)使用createDocumentFragment來(lái)解決添加大量節(jié)點(diǎn)時(shí)的性能問(wèn)題

5 頁(yè)面修改型API

前面我們提到節(jié)點(diǎn)創(chuàng)建型API袱结,它們只是創(chuàng)建節(jié)點(diǎn),并沒(méi)有真正修改到頁(yè)面內(nèi)容途凫,而是要調(diào)用·appendChild·來(lái)將其添加到文檔樹(shù)中垢夹。我在這里將這類會(huì)修改到頁(yè)面內(nèi)容歸為一類。
修改頁(yè)面內(nèi)容的api主要包括:appendChild维费,insertBefore果元,removeChildreplaceChild犀盟。

5.1 appendChild

appendChild我們?cè)谇懊嬉呀?jīng)用到多次而晒,就是將指定的節(jié)點(diǎn)添加到調(diào)用該方法的節(jié)點(diǎn)的子元素的末尾。

語(yǔ)法

  parent.appendChild(child);

child節(jié)點(diǎn)將會(huì)作為parent節(jié)點(diǎn)的最后一個(gè)子節(jié)點(diǎn)阅畴。
appendChild這個(gè)方法很簡(jiǎn)單欣硼,但是還有有一點(diǎn)需要注意:如果被添加的節(jié)點(diǎn)是一個(gè)頁(yè)面中存在的節(jié)點(diǎn),則執(zhí)行后這個(gè)節(jié)點(diǎn)將會(huì)添加到指定位置恶阴,其原本所在的位置將移除該節(jié)點(diǎn)诈胜,也就是說(shuō)不會(huì)同時(shí)存在兩個(gè)該節(jié)點(diǎn)在頁(yè)面上,相當(dāng)于把這個(gè)節(jié)點(diǎn)移動(dòng)到另一個(gè)地方冯事。
如果child綁定了事件焦匈,被移動(dòng)時(shí),它依然綁定著該事件昵仅。

例子:

<body>
  <div id="child">
    要被添加的節(jié)點(diǎn)
  </div>
  <br/>
  <br/>
  <br/>
  <div id="parent">
    要移動(dòng)的位置
  </div>        
  <input id="btnMove" type="button" value="移動(dòng)節(jié)點(diǎn)" />
</body>
<script>
  document.getElementById("btnMove").onclick = function(){
      var child = document.getElementById("child");
      document.getElementById("parent").appendChild(child);
  } 
</script>

運(yùn)行結(jié)果:


image

5.2 insertBefore

insertBefore用來(lái)添加一個(gè)節(jié)點(diǎn)到一個(gè)參照節(jié)點(diǎn)之前

語(yǔ)法

  parentNode.insertBefore(newNode,refNode);

parentNode表示新節(jié)點(diǎn)被添加后的父節(jié)點(diǎn)
newNode表示要添加的節(jié)點(diǎn)
refNode表示參照節(jié)點(diǎn)缓熟,新節(jié)點(diǎn)會(huì)添加到這個(gè)節(jié)點(diǎn)之前

例子:

<body>
  <div id="parent">
    父節(jié)點(diǎn)
    <div id="child">                
        子元素
    </div>
  </div>
  <input type="button" id="insertNode" value="插入節(jié)點(diǎn)" />
</body>
<script>
  var parent = document.getElementById("parent");
  var child = document.getElementById("child");
  document.getElementById("insertNode").onclick = function(){
    var newNode = document.createElement("div");
    newNode.textContent = "新節(jié)點(diǎn)"
    parent.insertBefore(newNode,child);
  }
</script>

運(yùn)行結(jié)果:
[圖片上傳失敗...(image-986770-1525955428155)]

關(guān)于第二個(gè)參數(shù)參照節(jié)點(diǎn)還有幾個(gè)注意的地方:
(1)refNode是必傳的,如果不傳該參數(shù)會(huì)報(bào)錯(cuò)
(2)如果refNode是undefined或null摔笤,則insertBefore會(huì)將節(jié)點(diǎn)添加到子元素的末尾

5.3 removeChild

刪除指定的子節(jié)點(diǎn)并返回

語(yǔ)法

  var deletedChild = parent.removeChild(node);

deletedChild指向被刪除節(jié)點(diǎn)的引用够滑,它等于node,被刪除的節(jié)點(diǎn)仍然存在于內(nèi)存中吕世,可以對(duì)其進(jìn)行下一步操作彰触。
注意:如果被刪除的節(jié)點(diǎn)不是其子節(jié)點(diǎn),則程序?qū)?huì)報(bào)錯(cuò)命辖。我們可以通過(guò)下面的方式來(lái)確笨鲆悖可以刪除:

if(node.parentNode){
    node.parentNode.removeChild(node);
}

運(yùn)行結(jié)果:


image

通過(guò)節(jié)點(diǎn)自己獲取節(jié)點(diǎn)的父節(jié)點(diǎn)分蓖,然后將自身刪除

5.4 replaceChild

replaceChild用于使用一個(gè)節(jié)點(diǎn)替換另一個(gè)節(jié)點(diǎn)

語(yǔ)法

  parent.replaceChild(newChild,oldChild);

newChild是替換的節(jié)點(diǎn),可以是新的節(jié)點(diǎn)尔许,也可以是頁(yè)面上的節(jié)點(diǎn)么鹤,如果是頁(yè)面上的節(jié)點(diǎn),則其將被轉(zhuǎn)移到新的位置
oldChild是被替換的節(jié)點(diǎn)

例子:

<body>
  <div id="parent">
    父節(jié)點(diǎn)
    <div id="child">                
        子元素
    </div>
  </div>
  <input type="button" id="insertNode" value="替換節(jié)點(diǎn)" />
</body>
<script>
  var parent = document.getElementById("parent");
  var child = document.getElementById("child");
  document.getElementById("insertNode").onclick = function(){
    var newNode = document.createElement("div");
    newNode.textContent = "新節(jié)點(diǎn)"
    parent.replaceChild(newNode,child)
  }

運(yùn)行結(jié)果:


image

5.5 頁(yè)面修改型API總結(jié)

頁(yè)面修改型API主要是這四個(gè)接口味廊,要注意幾個(gè)特點(diǎn):
(1)不管是新增還是替換節(jié)點(diǎn)蒸甜,如果新增或替換的節(jié)點(diǎn)是原本存在頁(yè)面上的,則其原來(lái)位置的節(jié)點(diǎn)將被移除余佛,也就是說(shuō)同一個(gè)節(jié)點(diǎn)不能存在于頁(yè)面的多個(gè)位置
(2)節(jié)點(diǎn)本身綁定的事件會(huì)不會(huì)消失柠新,會(huì)一直保留著。

6 節(jié)點(diǎn)查詢型API

6.1 document.getElementById

這個(gè)接口很簡(jiǎn)單衙熔,根據(jù)元素id返回元素登颓,返回值是Element類型,如果不存在該元素红氯,則返回null

語(yǔ)法

  var element = document.getElementById(id);

使用這個(gè)接口有幾點(diǎn)要注意:
(1)元素的Id是大小寫(xiě)敏感的框咙,一定要寫(xiě)對(duì)元素的id
(2)HTML文檔中可能存在多個(gè)id相同的元素,則返回第一個(gè)元素
(3)只從文檔中進(jìn)行搜索元素痢甘,如果創(chuàng)建了一個(gè)元素并指定id喇嘱,但并沒(méi)有添加到文檔中,則這個(gè)元素是不會(huì)被查找到的

例子:

<body>
  <p id="para1">Some text here</p>
  <button onclick="changeColor('blue');">blue</button>
  <button onclick="changeColor('red');">red</button>
</body>
<script>
  function changeColor(newColor) {
    var elem = document.getElementById("para1");
    elem.style.color = newColor;
  }
</script>

運(yùn)行結(jié)果:


image

6.2 document.getElementsByTagName

返回一個(gè)包括所有給定標(biāo)簽名稱的元素的HTML集合HTMLCollection塞栅。 整個(gè)文件結(jié)構(gòu)都會(huì)被搜索者铜,包括根節(jié)點(diǎn)。返回的 HTML集合是動(dòng)態(tài)的, 意味著它可以自動(dòng)更新自己來(lái)保持和 DOM 樹(shù)的同步而不用再次調(diào)用document.getElementsByTagName()

語(yǔ)法

  var elements = document.getElementsByTagName(name);

(1)如果要對(duì)HTMLCollection集合進(jìn)行循環(huán)操作放椰,最好將其長(zhǎng)度緩存起來(lái)作烟,因?yàn)槊看窝h(huán)都會(huì)去計(jì)算長(zhǎng)度,暫時(shí)緩存起來(lái)可以提高效率
(2)如果沒(méi)有存在指定的標(biāo)簽砾医,該接口返回的不是null拿撩,而是一個(gè)空的HTMLCollection
(3)name是一個(gè)代表元素的名稱的字符串。特殊字符 "*" 代表了所有元素如蚜。

例子:

<body>
  <div>div1</div>
  <div>div2</div>   
  <input type="button" value="顯示數(shù)量" id="btnShowCount"/>
  <input type="button" value="新增div" id="btnAddDiv"/>   
</body>
<script>
  var divList = document.getElementsByTagName("div");
  document.getElementById("btnAddDiv").onclick = function(){
    var div = document.createElement("div");
    div.textContent ="div" + (divList.length+1);
    document.body.appendChild(div);
  }
  document.getElementById("btnShowCount").onclick = function(){
    alert(divList.length);
  }
</script>

這段代碼中有兩個(gè)按鈕压恒,一個(gè)按鈕是顯示HTMLCollection元素的個(gè)數(shù),另一個(gè)按鈕可以新增一個(gè)div標(biāo)簽到文檔中错邦。前面提到HTMLCollcetion元素是即時(shí)的表示該集合是隨時(shí)變化的探赫,也就是是文檔中有幾個(gè)div,它會(huì)隨時(shí)進(jìn)行變化撬呢,當(dāng)我們新增一個(gè)div后伦吠,再訪問(wèn)HTMLCollection時(shí),就會(huì)包含這個(gè)新增的div。
運(yùn)行結(jié)果:


image

6.3 document.getElementsByName

getElementsByName主要是通過(guò)指定的name屬性來(lái)獲取元素讨勤,它返回一個(gè)即時(shí)的NodeList對(duì)象

語(yǔ)法

  var elements = document.getElementsByName(name) 

使用這個(gè)接口主要要注意幾點(diǎn):
(1)返回對(duì)象是一個(gè)即時(shí)的NodeList箭跳,它是隨時(shí)變化的
(2)在HTML元素中晨另,并不是所有元素都有name屬性潭千,比如div是沒(méi)有name屬性的,但是如果強(qiáng)制設(shè)置divname屬性借尿,它也是可以被查找到的
(3)在IE中刨晴,如果id設(shè)置成某個(gè)值,然后傳入getElementsByName的參數(shù)值和id值一樣路翻,則這個(gè)元素是會(huì)被找到的狈癞,所以最好不好設(shè)置同樣的值給idname

例子:

<script type="text/javascript">
  function getElements()
   {
   var x=document.getElementsByName("myInput");
   alert(x.length);
   }
</script>
<body>
  <input name="myInput" type="text" size="20" /><br />
  <input name="myInput" type="text" size="20" /><br />
  <input name="myInput" type="text" size="20" /><br />
  <br />
  <input type="button" onclick="getElements()" value="How many elements named 'myInput'?" />
</body>

運(yùn)行結(jié)果:
[圖片上傳失敗...(image-6abacd-1525955428156)]

6.4 document.getElementsByClassName

這個(gè)API是根據(jù)元素的class返回一個(gè)即時(shí)的HTMLCollection

語(yǔ)法

  var elements = document.getElementsByClassName(names); // or:
  var elements = rootElement.getElementsByClassName(names);
  • elements是一個(gè)實(shí)時(shí)集合,包含了找到的所有元素
  • names是一個(gè)字符串茂契,表示要匹配的類名列表蝶桶;類名通過(guò)空格分隔
  • getElementsByClassName可以在任何元素上調(diào)用,不僅僅是document掉冶。調(diào)用這個(gè)方法的元素將作為本次查找的根元素

這個(gè)接口有下面幾點(diǎn)要注意:
(1)返回結(jié)果是一個(gè)即時(shí)的HTMLCollection真竖,會(huì)隨時(shí)根據(jù)文檔結(jié)構(gòu)變化
(2)IE9以下瀏覽器不支持
(3)如果要獲取2個(gè)以上classname,可傳入多個(gè)classname厌小,每個(gè)用空格相隔恢共,例如

  var elements = document.getElementsByClassName("test1 test2");

例子:

  • 獲取所有class為 'test' 的元素
  var elements = document.getElementsByClassName('test');
  • 獲取所有class同時(shí)包括 'red' 和 'test' 的元素
  var elements = document.getElementsByClassName('red test');
  • id為'main'的元素的子節(jié)點(diǎn)中,獲取所有class為'test'的元素
  var elements = document.getElementById('main').getElementsByClassName('test');
  • 我們還可以對(duì)任意的HTMLCollection 使用Array.prototype的方法璧亚,調(diào)用時(shí)傳遞HTMLCollection 作為方法的參數(shù)讨韭。這里我們將查找到所有class為'test'的div元素:
  var testElements = document.getElementsByClassName('test');
  var testDivs = Array.prototype.filter.call(testElements, function(testElement){
    return testElement.nodeName === 'DIV';;
  });

6.5 document.querySelectordocument.querySelectorAll

這兩個(gè)API很相似,通過(guò)css選擇器來(lái)查找元素癣蟋,注意選擇器要符合CSS選擇器的規(guī)則

  • 6.5.1 document.querySelector

document.querySelector返回第一個(gè)匹配的元素透硝,如果沒(méi)有匹配的元素,則返回null

語(yǔ)法

  var element = document.querySelector(selectors);

注意疯搅,由于返回的是第一個(gè)匹配的元素濒生,這個(gè)api使用的深度優(yōu)先搜索來(lái)獲取元素。

例子:

<body>
  <div>
    <div>
      <span class="test">第三級(jí)的span</span>    
    </div>
  </div>
  <div class="test">            
    同級(jí)的第二個(gè)div
  </div>
  <input type="button" id="btnGet" value="獲取test元素" />
</body>
<script>
  document.getElementById("btnGet").addEventListener("click",function(){
    var element = document.querySelector(".test");
    alert(element.textContent);
  })
</script>

兩個(gè)class都包含“test”的元素秉撇,一個(gè)在文檔樹(shù)的前面甜攀,但是它在第三級(jí),另一個(gè)在文檔樹(shù)的后面琐馆,但它在第一級(jí)规阀,通過(guò)querySelector獲取元素時(shí),它通過(guò)深度優(yōu)先搜索瘦麸,拿到文檔樹(shù)前面的第三級(jí)的元素谁撼。
運(yùn)行結(jié)果:

image

  • 6.5.2 document.querySelectorAll
    返回的是所有匹配的元素,而且可以匹配多個(gè)選擇符

語(yǔ)法

  var elementList = document.querySelectorAll(selectors);
  • elementList是一個(gè)靜態(tài)的NodeList類型的對(duì)象
  • selectors是一個(gè)由逗號(hào)連接的包含一個(gè)或多個(gè)CSS選擇器的字符串
  • 如果selectors參數(shù)中包含CSS偽元素,則返回一個(gè)空的elementList

例子:

  var matches = document.querySelectorAll("div.note, div.alert");

返回一個(gè)文檔中所有的class"note"或者"alert"div元素

<body>
  <div class="test">
    class為test
  </div>
  <div id="test">
    id為test
  </div>
  <input id="btnShow" type="button" value="顯示內(nèi)容" />
</body>
<script>
  document.getElementById("btnShow").addEventListener("click",function(){
    var elements = document.querySelectorAll("#test,.test");    
    for(var i = 0,length = elements.length;i<length;i++){
        alert(elements[i].textContent);
    }   
  })
</script>

這段代碼通過(guò)querySelectorAll,使用id選擇器和class選擇器選擇了兩個(gè)元素厉碟,并依次輸出其內(nèi)容喊巍。要注意兩點(diǎn):
(1)querySelectorAll也是通過(guò)深度優(yōu)先搜索,搜索的元素順序和選擇器的順序無(wú)關(guān)
(2)返回的是一個(gè)非即時(shí)的NodeList箍鼓,也就是說(shuō)結(jié)果不會(huì)隨著文檔樹(shù)的變化而變化
兼容性問(wèn)題:querySelectorquerySelectorAll在ie8以下的瀏覽器不支持崭参。

運(yùn)行結(jié)果:


image

7 節(jié)點(diǎn)關(guān)系型API

在html文檔中的每個(gè)節(jié)點(diǎn)之間的關(guān)系都可以看成是家譜關(guān)系,包含父子關(guān)系款咖,兄弟關(guān)系等等

7.1 父關(guān)系型API

7.1.1 parentNode

每個(gè)節(jié)點(diǎn)都有一個(gè)parentNode屬性何暮,它表示元素的父節(jié)點(diǎn)。Element的父節(jié)點(diǎn)可能是Element铐殃,Document或DocumentFragment

7.1.2 parentElement

返回元素的父元素節(jié)點(diǎn)海洼,與parentNode的區(qū)別在于,其父節(jié)點(diǎn)必須是一個(gè)Element富腊,如果不是坏逢,則返回null

7.2 子關(guān)系型APPI

7.2.1 childNodes

返回一個(gè)即時(shí)的NodeList,表示元素的子節(jié)點(diǎn)列表赘被,子節(jié)點(diǎn)可能會(huì)包含文本節(jié)點(diǎn)是整,注釋節(jié)點(diǎn)等

7.2.2 children:

一個(gè)即時(shí)的HTMLCollection,子節(jié)點(diǎn)都是Element帘腹,IE9以下瀏覽器不支持
children屬性為只讀屬性贰盗,對(duì)象類型為HTMLCollection,你可以使用elementNodeReference.children[1].nodeName來(lái)獲取某個(gè)子元素的標(biāo)簽名稱

7.2.3 firstChild

只讀屬性返回樹(shù)中節(jié)點(diǎn)的第一個(gè)子節(jié)點(diǎn)阳欲,如果節(jié)點(diǎn)是無(wú)子節(jié)點(diǎn)舵盈,則返回 null

7.2.4 lastChild

返回當(dāng)前節(jié)點(diǎn)的最后一個(gè)子節(jié)點(diǎn)。如果父節(jié)點(diǎn)為一個(gè)元素節(jié)點(diǎn)球化,則子節(jié)點(diǎn)通常為一個(gè)元素節(jié)點(diǎn)秽晚,或一個(gè)文本節(jié)點(diǎn),或一個(gè)注釋節(jié)點(diǎn)筒愚。如果沒(méi)有子節(jié)點(diǎn)赴蝇,則返回null

7.2.5 hasChildNodes

返回一個(gè)布爾值,表明當(dāng)前節(jié)點(diǎn)是否包含有子節(jié)點(diǎn).

7.3 兄弟關(guān)系型API

7.3.1 previousSibling

返回當(dāng)前節(jié)點(diǎn)的前一個(gè)兄弟節(jié)點(diǎn),沒(méi)有則返回null
Gecko內(nèi)核的瀏覽器會(huì)在源代碼中標(biāo)簽內(nèi)部有空白符的地方插入一個(gè)文本結(jié)點(diǎn)到文檔中.因此,使用諸如Node.firstChildNode.previousSibling之類的方法可能會(huì)引用到一個(gè)空白符文本節(jié)點(diǎn), 而不是使用者所預(yù)期得到的節(jié)點(diǎn)

7.3.2 previousElementSibling

previousElementSibling返回當(dāng)前元素在其父元素的子元素節(jié)點(diǎn)中的前一個(gè)元素節(jié)點(diǎn),如果該元素已經(jīng)是第一個(gè)元素節(jié)點(diǎn),則返回null,該屬性是只讀的。注意IE9以下瀏覽器不支持

7.3.3 nextSibling

Node.nextSibling是一個(gè)只讀屬性巢掺,返回其父節(jié)點(diǎn)的childNodes列表中緊跟在其后面的節(jié)點(diǎn)句伶,如果指定的節(jié)點(diǎn)為最后一個(gè)節(jié)點(diǎn),則返回null
Gecko內(nèi)核的瀏覽器會(huì)在源代碼中標(biāo)簽內(nèi)部有空白符的地方插入一個(gè)文本結(jié)點(diǎn)到文檔中.因此,使用諸如Node.firstChildNode.previousSibling之類的方法可能會(huì)引用到一個(gè)空白符文本節(jié)點(diǎn), 而不是使用者所預(yù)期得到的節(jié)點(diǎn)

7.3.4 nextElementSibling

nextElementSibling返回當(dāng)前元素在其父元素的子元素節(jié)點(diǎn)中的后一個(gè)元素節(jié)點(diǎn),如果該元素已經(jīng)是最后一個(gè)元素節(jié)點(diǎn),則返回null,該屬性是只讀的陆淀。注意IE9以下瀏覽器不支持

8 元素屬性型API

8.1 setAttribute

設(shè)置指定元素上的一個(gè)屬性值考余。如果屬性已經(jīng)存在,則更新該值; 否則將添加一個(gè)新的屬性用指定的名稱和值

語(yǔ)法

  element.setAttribute(name, value);

其中name是特性名轧苫,value是特性值楚堤。如果元素不包含該特性,則會(huì)創(chuàng)建該特性并賦值。

例子:

<body>
  <div id="div1">ABC</div>
</body>
<script>  
  let div1 = document.getElementById("div1"); 
  div1.setAttribute("align", "center");
</script>

運(yùn)行結(jié)果:


image

如果元素本身包含指定的特性名為屬性身冬,則可以世界訪問(wèn)屬性進(jìn)行賦值衅胀,比如下面兩條代碼是等價(jià)的:

  element.setAttribute("id","test");
  element.id = "test";

8.2 getAttribute

getAttribute()返回元素上一個(gè)指定的屬性值。如果指定的屬性不存在酥筝,則返回null""(空字符串)

語(yǔ)法

  let attribute = element.getAttribute(attributeName);  

attribute是一個(gè)包含attributeName屬性值的字符串滚躯。attributeName是你想要獲取的屬性值的屬性名稱

例子:

<body>
  <div id="div1">ABC</div>
</body>
<script>  
  let div1 = document.getElementById("div1");
  let align = div1.getAttribute("align");
  alert(align);
</script>  

運(yùn)行結(jié)果:


image

8.3 removeAttribute

removeAttribute()從指定的元素中刪除一個(gè)屬性

語(yǔ)法

  element.removeAttribute(attrName)

attrName是一個(gè)字符串,將要從元素中刪除的屬性名

例子:

<body>
  <div id="div1" style="color:red" width="200px">ABC
   </div>
</body>
<script>  
  let div = document.getElementById("div1")
  div.removeAttribute("style");
</script>

在運(yùn)行之前div有個(gè)style="color:red"的屬性樱哼,在運(yùn)行之后這個(gè)屬性就被刪除了

運(yùn)行結(jié)果:


image

9 元素樣式型API

9.1 window.getComputedStyle

Window.getComputedStyle()方法給出應(yīng)用活動(dòng)樣式表后的元素的所有CSS屬性的值哀九,并解析這些值可能包含的任何基本計(jì)算
假設(shè)某個(gè)元素并未設(shè)置高度而是通過(guò)其內(nèi)容將其高度撐開(kāi)剿配,這時(shí)候要獲取它的高度就要用到getComputedStyle

語(yǔ)法

  var style = window.getComputedStyle(element[, pseudoElt]);

element是要獲取的元素搅幅,pseudoElt指定一個(gè)偽元素進(jìn)行匹配。
返回的style是一個(gè)CSSStyleDeclaration對(duì)象呼胚。
通過(guò)style可以訪問(wèn)到元素計(jì)算后的樣式

9.2 getBoundingClientRect

getBoundingClientRect用來(lái)返回元素的大小以及相對(duì)于瀏覽器可視窗口的位置

語(yǔ)法

  var clientRect = element.getBoundingClientRect();

clientRect是一個(gè)DOMRect對(duì)象茄唐,包含left,top蝇更,right沪编,bottom,它是相對(duì)于可視窗口的距離年扩,滾動(dòng)位置發(fā)生改變時(shí)蚁廓,它們的值是會(huì)發(fā)生變化的。除了IE9以下瀏覽器厨幻,還包含元素的height和width等數(shù)據(jù)

9.3 直接修改元素的樣式

例子:

  elem.style.color = 'red';
  elem.style.setProperty('font-size', '16px');
  elem.style.removeProperty('color');

9.4 動(dòng)態(tài)添加樣式規(guī)則

例子:

  var style = document.createElement('style');
  style.innerHTML = 'body{color:red} #top:hover{background-color: red;color: white;}';
  document.head.appendChild(style););

10 總結(jié)

JavaScript中的API太多了相嵌,將這些API記住并熟練使用對(duì)JavaScript的學(xué)習(xí)是有很大的提高

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市况脆,隨后出現(xiàn)的幾起案子饭宾,更是在濱河造成了極大的恐慌,老刑警劉巖格了,帶你破解...
    沈念sama閱讀 216,692評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件看铆,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡盛末,警方通過(guò)查閱死者的電腦和手機(jī)弹惦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)悄但,“玉大人棠隐,你說(shuō)我怎么就攤上這事∷隳” “怎么了宵荒?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,995評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我报咳,道長(zhǎng)侠讯,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,223評(píng)論 1 292
  • 正文 為了忘掉前任暑刃,我火速辦了婚禮厢漩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘岩臣。我一直安慰自己溜嗜,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布架谎。 她就那樣靜靜地躺著炸宵,像睡著了一般。 火紅的嫁衣襯著肌膚如雪谷扣。 梳的紋絲不亂的頭發(fā)上土全,一...
    開(kāi)封第一講書(shū)人閱讀 51,208評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音会涎,去河邊找鬼裹匙。 笑死,一個(gè)胖子當(dāng)著我的面吹牛末秃,可吹牛的內(nèi)容都是我干的概页。 我是一名探鬼主播,決...
    沈念sama閱讀 40,091評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼练慕,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼惰匙!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起贺待,我...
    開(kāi)封第一講書(shū)人閱讀 38,929評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤徽曲,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后麸塞,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體秃臣,經(jīng)...
    沈念sama閱讀 45,346評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評(píng)論 2 333
  • 正文 我和宋清朗相戀三年哪工,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了奥此。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,739評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡雁比,死狀恐怖稚虎,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情偎捎,我是刑警寧澤蠢终,帶...
    沈念sama閱讀 35,437評(píng)論 5 344
  • 正文 年R本政府宣布序攘,位于F島的核電站,受9級(jí)特大地震影響寻拂,放射性物質(zhì)發(fā)生泄漏程奠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評(píng)論 3 326
  • 文/蒙蒙 一祭钉、第九天 我趴在偏房一處隱蔽的房頂上張望瞄沙。 院中可真熱鬧,春花似錦慌核、人聲如沸距境。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,677評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)垫桂。三九已至,卻和暖如春扒接,著一層夾襖步出監(jiān)牢的瞬間伪货,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,833評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工钾怔, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蒙挑。 一個(gè)月前我還...
    沈念sama閱讀 47,760評(píng)論 2 369
  • 正文 我出身青樓宗侦,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親忆蚀。 傳聞我的和親對(duì)象是個(gè)殘疾皇子矾利,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評(píng)論 2 354

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

  • ??DOM(文檔對(duì)象模型)是針對(duì) HTML 和 XML 文檔的一個(gè) API(應(yīng)用程序編程接口)男旗。 ??DOM 描繪...
    霜天曉閱讀 3,644評(píng)論 0 7
  • 第3章 基本概念 3.1 語(yǔ)法 3.2 關(guān)鍵字和保留字 3.3 變量 3.4 數(shù)據(jù)類型 5種簡(jiǎn)單數(shù)據(jù)類型:Unde...
    RickCole閱讀 5,124評(píng)論 0 21
  • Node類型 DOM1級(jí)定義了一個(gè)Node接口,該接口由DOM中所有節(jié)點(diǎn)類型實(shí)現(xiàn)欣鳖。這個(gè)Node接口在JS中是作為N...
    Maggie_77閱讀 420評(píng)論 0 0
  • 原文地址:http://luopq.com/2015/11/30/javascript-dom/ 文本整理了jav...
    鷓鴣少閱讀 348評(píng)論 0 1
  • 那并不難受察皇,并不痛苦,因?yàn)槲沂峙踔鳷A的相片泽台,小心翼翼什荣,因?yàn)檫@是最后一次。我很珍惜怀酷。 我猜稻爬,當(dāng)時(shí)對(duì)著相...
    觸情閱讀 237評(píng)論 2 0