前面的话

  说到最常见的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扩充的新方法,兼容性不是很好,这些新方法将在续篇进行详细介绍

  欢迎交流

深入理解javascript选择器API系列第一篇——4种元素选择器的更多相关文章

  1. 深入理解javascript函数进阶系列第一篇——高阶函数

    前面的话 前面的函数系列中介绍了函数的基础用法.从本文开始,将介绍javascript函数进阶系列,本文将详细介绍高阶函数 定义 高阶函数(higher-order function)指操作函数的函数 ...

  2. 深入理解javascript选择器API系列第二篇——getElementsByClassName

    × 目录 [1]使用 [2]classList [3]扩展 前面的话 既然有getElementById()和getElementsByTagName()方法,为什么没有getElementsByCl ...

  3. 深入理解javascript函数进阶系列第二篇——函数柯里化

    前面的话 函数柯里化currying的概念最早由俄国数学家Moses Schönfinkel发明,而后由著名的数理逻辑学家Haskell Curry将其丰富和发展,currying由此得名.本文将详细 ...

  4. 深入理解DOM事件机制系列第一篇——事件流

    × 目录 [1]历史 [2]事件冒泡 [3]事件捕获[4]事件流 前面的话 javascript操作CSS称为脚本化CSS,而javascript与HTML的交互是通过事件实现的.事件就是文档或浏览器 ...

  5. 深入理解脚本化CSS系列第一篇——脚本化行内样式

    × 目录 [1]用法 [2]属性 [3]方法 前面的话 脚本化CSS,通俗点说,就是使用javascript来操作CSS.引入CSS有3种方式:外部样式,内部样式和行间样式.本文将主要介绍脚本化行间样 ...

  6. 深入理解DOM事件类型系列第一篇——鼠标事件

    × 目录 [1]类型 [2]顺序 [3]坐标位置[4]修改键[5]相关元素[6]鼠标按键[7]滚轮事件[8]移动设备 前面的话 鼠标事件是web开发中最常用的一类事件,毕竟鼠标是最主要的定位设备.本文 ...

  7. 深入理解javascript选择器API系列第三篇——h5新增的3种selector方法

    × 目录 [1]方法 [2]非实时 [3]缺陷 前面的话 尽管DOM作为API已经非常完善了,但是为了实现更多的功能,DOM仍然进行了扩展,其中一个重要的扩展就是对选择器API的扩展.人们对jQuer ...

  8. 深入理解javascript选择器API系列第三篇——HTML5新增的3种selector方法

    前面的话 尽管DOM作为API已经非常完善了,但是为了实现更多的功能,DOM仍然进行了扩展,其中一个重要的扩展就是对选择器API的扩展.人们对jQuery的称赞,很多是由于jQuery方便的元素选择器 ...

  9. 深入理解javascript函数系列第一篇——函数概述

    × 目录 [1]定义 [2]返回值 [3]调用 前面的话 函数对任何一门语言来说都是一个核心的概念.通过函数可以封装任意多条语句,而且可以在任何地方.任何时候调用执行.在javascript里,函数即 ...

随机推荐

  1. SymmetricDS 快速和灵活的数据库复制

    开始谈谈开源的SymmetricDS,谈谈实际使用中,遇到的一些问题和解决办法.持续更新: SymmetricDS 快速和灵活的数据库复制 实际使用 和 埋过的坑 (一)知识篇 SymmetricDS ...

  2. 安装并使用PHPunit

    安装并使用PHPunit Linux 下安装PHPunit PHP 档案包 (PHAR)  要获取 PHPUnit,最简单的方法是下载 PHPUnit 的 PHP 档案包 (PHAR),它将 PHPU ...

  3. 关于javascript中的this关键字

    this是非常强大的一个关键字,但是如果你不了解它,可能很难正确的使用它. 下面我解释一下如果在事件处理中使用this. 首先我们讨论一下下面这个函数中的this关联到什么. function doS ...

  4. python selenium

    https://segmentfault.com/a/1190000007249396?_ea=1293878

  5. Linux Socket 网络编程

    Linux下的网络编程指的是socket套接字编程,入门比较简单.在学校里学过一些皮毛,平时就是自学玩,没有见识过真正的socket编程大程序,比较遗憾.总感觉每次看的时候都有收获,但是每次看完了之后 ...

  6. 好好了解一下Cookie

    Cookie的诞生 由于HTTP协议是无状态的,而服务器端的业务必须是要有状态的.Cookie诞生的最初目的是为了存储web中的状态信息,以方便服务器端使用.比如判断用户是否是第一次访问网站.目前最新 ...

  7. 架构之路(九)Session Per Request

    前面的两篇反应很差:没评论没赞.很伤心啊,为什么呢?搞得我好长一段时间都没更新了——呵呵,好吧,我承认,这只是我的借口.不过,还是希望大家多给反馈.没有反馈,我就只能猜了:前面两篇是不是写得太“粗”了 ...

  8. Entity Framework 6 Recipes 2nd Edition(10-4)译 -> 从存储过程返回一个复杂类型

    10-4. 从存储过程返回一个复杂类型 问题 想在方法中使用一个返回复杂类型的存储过程 解决方案 假设我们已经有如Figure 10-3.所示的模型,该Employee (雇员)模型包含Employe ...

  9. .NET 基础一步步一幕幕[方法、结构、枚举]

    方法.结构.枚举 方法: 将一堆代码进行重用的一种机制. 语法: [访问修饰符] 返回类型 <方法名>(参数列表){ 方法主体: } 返回值类型:如果不需要写返回值,写void 方法名:P ...

  10. Html5 简单选择排序演示

    简单选择排序,是选择排序算法的一种.基本思想:每趟从待排序的记录中选出关键字最小的记录,顺序放在已排序的记录序列末尾,直到全部排序结束为止.由于在每次循环中,会对数值相等的元素改变位置,所以属于非稳定 ...