getElementById

任何HTML元素可以有一个id属性,在文档中该值必须唯一。

如果浏览器中出现多个相同的id名,CSS样式对所有该id名的元素都生效,但 JS 仅对第一个出现该id的元素生效。


[ 方法说明 ]该方法接收一个参数:要取得元素的id。如果找到,则返回该元素;如果不存在,则返回null。

<div id="myDiv"></div>
<script>
   var div1 = document.getElementById('myDiv');      // <div id="myDiv"></div>
   var div2 = document.getElementById('mydiv');      // //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);

[ 拓展理解 ]

说到最常见的DOM应用,恐怕就要数取得特定的某个或某组元素的引用了。DOM定义了许多方式来选取元素,包括getElementById()、getElementsByTagName()、getElementsByName()和document.all4种。

getElementsByName()方法并不常用,再加上已经废弃的document.all。

实际上,常用的获取元素的方法就getElementById()和getElementsByTagName()两种。

getElementsByClassName()不也是吗?的确,但和querySelector()等方法都是HTML5的新方法,兼容性不是很好。

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

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