前面的話
說到最常見的DOM應用,恐怕就要數取得特定的某個或某組元素的引用了。DOM定義了許多方式來選取元素,包括getElementById()、getElementsByTagName()、getElementsByName()和document.all4種。接下來,將對這4種方法進行詳細介紹
getElementById()
任何HTML元素可以有一個id屬性,在文檔中該值必須唯一
[注意]若瀏覽器中出現多個id名的情況,CSS樣式對所有該id名的元素都生效,但javascript腳本僅對第一個出現該id名的元素生效

getElementById()該方法接收一個參數:要取得元素的id,若找到則返回該元素,若不存在則返回null
<div id="myDiv"></div> <script> var div1 = document.getElementById('myDiv'); var div2 = document.getElementById('mydiv'); console.log(div1);//<div id="myDiv"></div> console.log(div2);//null </script>
關于getElementById()方法,IE7-瀏覽器有兩個bug
【1】該方法對匹配元素的ID不區分大小寫
<div id="myDiv" style="height:20px;"></div> <script> var div1 = document.getElementById('mydiv'); //在標準瀏覽器下報錯,但在IE7-瀏覽器下,id為'myDiv'的元素的背景顏色變為品紅色 div1.style.backgroundColor = 'pink'; </script>
【2】表單元素的name屬性也會被當作ID屬性識別出來。因此為了避免這種問題,最好不讓表單元素的name屬性和其他元素的ID屬性相同
<button name="test">0</button> <script> var myDiv = document.getElementById('test'); //在標準瀏覽器下報錯,但在IE7-瀏覽器中會輸出0 console.log(myDiv.innerHTML); </script>
[注意]如果在HTML文檔中元素中存在某id屬性,并且如果Window對象沒有此名字的屬性, Window對象會賦予一個屬性,它的名字是id屬性的值,而它們的值指向表示文檔元素的HTMLElement對象,因此,元素ID隱式地成為了全局變量,與getElementById(id)方法的效果相同
<div id="test"></div> <button id="btn">按鈕一</button> <button id="location">按鈕二</button> <script> var oBtn = document.getElementById('btn'); var oDiv = document.getElementById('test'); oBtn.onclick = function(){ //通過getElementById()方法獲取id為test的對象 oDiv.style.height='10px'; //通過id屬性獲取相同的對象 test.style.backgroundColor ='pink'; } //由于location本身就是window對象下的屬性,已經被占用,所以無法表示id=location的元素 location.onclick = function(){ alert(2); } </script>
在IE瀏覽器中,HTML某些元素如果有name屬性,也與id屬性相同,隱式地成為全局變量,包括:
<a> <embed> <form> <iframe> <img> <object>
id是唯一的,但name屬性并不是唯一的。具有該名稱的隱式全局變量會引用一個類數組對象,包括所有該命名的元素
<a href="#" name="test">a元素1</a> <a href="#" name="test">a元素2</a> <div id="test">div元素</div> <script> //IE瀏覽器中,兩個a元素和一個div元素字體都變成紅色 for(var i = 0; i < test.length; i++){ test[i].style.color = 'red'; } </script>
【丟失的this】
document.getElementById這個方法名實在有點過長,可以用一個短的函數來代替它
var getId = function(id){ return document.getElementById(id); }
但是,為什么不能用下面這種更簡單的形式呢?
var getId = document.getElementById; getId('div1');
上面的這段代碼中會拋出異常

這是因為document.getElementById方法的內部實現需要用到this,這個this本來被期望指向document,當getElementById方法作為document對象的屬性被調用時,方法內部的this確實指向document。但當用getId來引用document.getElementById之后,再調用getId,此時就成了普通函數調用,函數內部的this指向了window,而不是document
代碼修改如下,可以取得id為'div1'的元素
<div id="div1"></div> <script> var getId = document.getElementById; console.log(getId.call(document,'div1')); </script>
或者,可以這樣修改
var getId = document.getElementById.bind(document);
最終結果如下

getElementsByTagName()
getElementsByTagName()方法接收一個參數,即要取得元素的標簽名,而返回的是包含0或多個元素的類數組對象HTMLCollection。可以使用方括號語法或item()方法來訪問類數組對象中的項,length屬性表示對象中元素的數量
<div>元素一</div> <div>元素二</div> <script> var divs = document.getElementsByTagName('div'); divs[0].style.color = 'red'; divs.item(1).style.backgroundColor = 'pink'; </script>
[注意]通過getElementsByTagName()方法取得的類數組對象有一個namedItem()方法,可以通過元素的name屬性取得集合中的第一個值。safari和IE不支持該方法
<div>元素一</div> <div name='test'>元素二</div> <div name='test'>元素三</div> <script> var divs = document.getElementsByTagName('div'); divs.namedItem('test').style.color = 'red'; </script>
getElementsByTagName()方法可以用于document對象,也可以用于element元素對象,用于調用該方法的元素的后代元素
<ul id='myUl'> <li>1</li> <li>2</li> </ul> <script> var oUl = document.getElementById('myUl'); var lis = oUl.getElementsByTagName('li'); lis[0].style.color = 'red'; </script>
getElementsByName()
getElementsByName()方法會返回帶有給定name特性的所有元素
<button name='test'>按鈕一</button> <button name='test'>按鈕二</button> <script> var button = document.getElementsByName('test'); button[0].style.color = 'red'; </script>
關于getElementsByName()方法,IE瀏覽器與其他瀏覽器相比,有三個不同之處
【1】IE9-瀏覽器只支持在表單元素上使用getElementsByName()方法
<div name='test'>元素一</div> <div name='test'>元素二</div> <script> //標準瀏覽器下,元素一顏色變為紅色,但在IE9-瀏覽器下會報錯 var divs = document.getElementsByName('test'); divs[0].style.color = 'red'; </script>
【2】IE9-瀏覽器中使用getElementsByName()方法也會返回id屬性匹配的元素。因此,不要將name和id屬性設置為相同的值
<button name='test'>按鈕一</button> <button name='test'>按鈕二</button> <button id="test">按鈕三</button> <script> //標準瀏覽器下,按鈕三不變色,但IE9-瀏覽器下,按鍵三也變成紅色 var buttons = document.getElementsByName('test'); for(var i = 0; i < buttons.length; i++){ buttons[i].style.color = 'red'; } </script>
【3】如果對getElementsByName()方法取得的類數組對象使用namedItem()方法,因為每一項的name屬性都相同,所以只會返回第一項
[注意]只有IE8——IE11瀏覽器支持
<button name='test'>按鈕一</button> <button name='test'>按鈕二</button> <script> var buttons = document.getElementsByName('test'); buttons.namedItem('test').style.color = 'red'; </script>
document.all
在DOM標準化之前,IE4就引入了document.all[]集合來表示文檔中的所有元素
<div>div</div> <button>按鈕</button> <script> console.log(document.all);//[html, head, meta, title, body, div, button, script] //標準瀏覽器返回8,而IE8-瀏覽器返回9,由于它把文檔聲明<!DOCTYPE html>識別為注釋,且把注釋識別為元素,所以多1個 console.log(document.all.length); </script>
現在document.all方法已經棄用,要取得類似效果,可以使用document.getElementsByTagName('*')方法,*表示匹配所有元素
<div>div</div> <button>按鈕</button> <script> console.log(document.getElementsByTagName('*'));//[html, head, meta, title, body, div, button, script] //標準瀏覽器返回8,而IE8-瀏覽器返回9,由于它把文檔聲明<!DOCTYPE html>識別為注釋,且把注釋識別為元素,所以多1個 console.log(document.getElementsByTagName('*').length); </script>
最后
getElementsByName()方法并不常用,再加上已經廢棄的document.all。實際上,常用的獲取元素的方法就getElementById()和getElementsByTagName()兩種。getElementsByClassName()不也是嗎?確實是,但它和querySelector()等方法都是HTML5擴充的新方法,兼容性不是很好,這些新方法將在續篇進行詳細介紹
歡迎交流
文章列表