前些日子,碰到过一个比较麻烦的问题。想从 document.getElementsByTagName()方法的返回值中取出某个特定的元素。一开始以为它的返回值是一个数组,结果,大错特错。它返回的是一个 DOM 对象,可以遍历,有 length 属性,但不是数组。
证据在这里:

XML/HTML code ?
1
2
3
4
5
6
7
8
<script>
    window.onload = function() {
       var divs = document.getElementsByTagName("div");
       document.getElementById("info").innerHTML = !!(divs instanceof Array);
    }
</script>
<div></div>
<div id="info"></div>

把它当Array用的兄弟姐妹小心了。
既然不是Array,那么它到底是什么呢?
继续探索之:

XML/HTML code ?
1
2
3
4
5
6
7
8
<script>
    window.onload = function() {
       var divs = document.getElementsByTagName("div");
       document.getElementById("info").innerHTML = Object.prototype.toString.call(divs);
    }
</script>
<div></div>
<div id="info"></div>

在各浏览器中打开:
IE: [object Object]
Firefox:[object HTMLCollection]
Chrome/Safari /Opera:[object NodeList]
这个结果让人很纠结,5 个浏览器3种结果,其中 IE 和Firefox貌似不太合群。
无奈,干脆去查查标准。

W3C DOM3中 document.getElementsByTagName() 方法的返回值

getElementsByTagName() 是 W3C 从  DOM1就引进的获取拥有相同标签名称的一组元素的方法。而在 DOM2 和  DOM3 保留了这个接口。
它的返回值是一个 NodeList。
一下是它的接口说明:

C/C++ code ?
1
2
3
4
5
interface Element : Node {
   ...
   NodeList getElementsByTagName(in DOMString name);
   ...
}

DOM3中关于 getElementsByTagName接口的详细说明,请看这里: getElementsByTagName

主流浏览器中 getElementsByTagName()方法的返回值

各浏览器官方文档中对于此方法的说明也符合W3C的规定,都是返回的 NodeList类型的对象集合。
看来,Firefox跟自己矛盾了,哈哈。
关于资料,看这里
Mozilla 官方: document.getElementsByName
Safari官方 Webkit DOM: getElementsByName
MSDN官方:  getElementsByName Method
那么什么是NodeList接口呢,它又有什么特性呢,接着往下看。

NodeList 接口

W3C DOM3规定,NodeList是一个有序的节点集合。

它的属性和方法:
NodeList . length
   返回集合中的对象个数。length是只读属性。
Node = NodeList . item(index)
     从集合中返回指定索引的节点。

可见,NodeList类型的对象可以使用 item()方法获取其中的节点。
在 Firefox,Chrome和Safari中,对于NodeList的定义与 W3C相同。
在 IE中,NodeList继承了Collection接口,所以,NodeList对象支持Collection接口中的方法。
Opera 没有找到相关说明。
关于 NodeList的说明资料:
W3C DOM3:  Interface NodeList
Mozilla:  NodeList
Safari官方Webkit DOM:  NodeList
MSDN NodeList接口: NodeList Class
下面开始介绍,如何

从 document.getElementsByTagName()方法的返回值中取值

汇总表:
[img=https://lh6.googleusercontent.com/_RMajOid94m4gGaf92o36i2wawsFPzrr3wNCHh3Zw6Avo6-eVAUTp-KtIoTA7SbzEIBkbaWIrdzP2-6zqlJla3fMOSzI0nW5lVhOMrBQ4EdziQag][/img]
注:
1. 红色代表不支持,绿色代表支持。
2. 对于 NodeList[name]、NodeList(name) 和 NodeList.namedItem(name)这 3行,IE的支持情况跟其他支持该方式的浏览器之间也存在差异,当document,getElementsByTagName()的返回值中存在相同 name 的元素时,IE返回一组元素,而其他支持的浏览器只返回符合的第一个元素。

可见,在IE和Opera 中,getElementsByTagName()返回值更像一个 HTMLcollection;而在Firefox中,介于 HTMLcollection和 NodeList之间。

NodeList[index]和 NodeList[id]

代码:

XML/HTML code ?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script type="text/javascript">
   window.onload = function() {
       var spans = document.getElementsByTagName("span");
       var span2 = spans[1];
       var span3 = spans["span3"];
       document.getElementById("info").innerHTML = "<br/>NodeList[index].id : " + span2.id
                                                                   + "<br/>NodeList[id].id : " + span3.id;
   }
</script>
<span id="span1"></span>
<span id="span2"></span>
<span id="span3"></span>
<div id="info"></div>

测试结果在各浏览器中都相同:
NodeList[index].id : span2
NodeList[name].id : span3

NodeList[name]

测试代码:

XML/HTML code ?
1
2
3
4
5
6
7
8
9
10
11
12
<script type="text/javascript">
    window.onload = function() {
       var inputs = document.getElementsByTagName("input");
       var input_1 = inputs["input1"];
       document.getElementById("info").innerHTML += "<br/>NodeList[name].id : " + input_1.id;
    }
</script>
<input id="ipt1" name="input1">
<input id="ipt2" name="input2">
<input id="ipt3" name="input3">
<div id="info"></div>

结果:
Firefox、Opera和IE,都输出的是:NodeList[name].id : ipt1
Chrome 和Safari报错,它们不支持这种方式。

另外,Firefox和Opera中,此方法存在差异,因为 name 属性可以相同,当存在多个相同 name 的元素时,Firefox和Opera中取出的还是第一个,而IE取出的则是一个组。
看代码:

XML/HTML code ?
1
2
3
4
5
6
7
8
9
10
11
12
13
<script type="text/javascript">
    window.onload = function() {
       var inputs = document.getElementsByTagName("input");
       var input_1 = inputs["input1"];
       document.getElementById("info").innerHTML += "NodeList[name].id : " + input_1.id+
               "<br/>NodeList[name].length : " + input_1.length;
    }
</script>
<input id="ipt1" name="input1">
<input id="ipt2" name="input1">
<input id="ipt3" name="input3">
<div id="info"></div>

在Firefox和Opera中输出:
NodeList[name].id : ipt1
NodeList[name].length : undefined
IE 中:
NodeList[name].id : undefined
NodeList[name].length : 2

NodeList(index)

测试用例代码:

XML/HTML code ?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script type="text/javascript">
   window.onload = function() {
       var spans = document.getElementsByTagName("span");
       try {
           var span2 = spans(1);
           document.getElementById("info").innerHTML = "NodeList(index).id: " + span2.id;
       } catch(err) {
           document.getElementById("info").innerHTML = "NodeList(index) : " + err;
       }
   }
</script>
<span id="span1"></span>
<span id="span2"></span>
<div id="info"></div>

以上代码,只有在Firefox中报错:TypeError: spans is not a function
其他浏览器中的输出:NodeList(index).id: span2

NodeList(id)

测试代码:

XML/HTML code ?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script type="text/javascript">
    window.onload = function() {
        var spans = document.getElementsByTagName("span");
        try {
            var span2 = spans("span2");
            document.getElementById("info").innerHTML = "NodeList(id).id: " + span2.id;
        } catch(err) {
            document.getElementById("info").innerHTML = "NodeList(id) : " + err;
        }
    }
</script>
<span id="span1"></span>
<span id="span2"></span>
<div id="info"></div>

Firefox、 Chrome和Safari报错,IE 和 Opera 依然支持。

NodeList(name)

看测试用例代码:

XML/HTML code ?
1
2
3
4
5
6
7
8
9
10
11
12
13
<script type="text/javascript">
    window.onload = function() {
       var inputs = document.getElementsByTagName("input");
       var input_1 = inputs("input1");
       document.getElementById("info").innerHTML += "NodeList(name).id : " + input_1.id+
               "<br/>NodeList(name).length : " + input_1.length;
    }
</script>
<input id="ipt1" name="input1">
<input id="ipt2" name="input1">
<input id="ipt3" name="input3">
<div id="info"></div>

以上代码,IE和Opera都支持。但是,支持情况也有差异,同 NodeList[name]。
Firefox和Webkit浏览器都不支持。

NodeList.item(index)

看测试用例代码:

XML/HTML code ?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script type="text/javascript">
    window.onload = function() {
        var spans = document.getElementsByTagName("span");
        try {
            var span2 = spans.item(1);
            document.getElementById("info").innerHTML = "NodeList.item(idx).id: " + span2.id;
        } catch(err) {
            document.getElementById("info").innerHTML = "NodeList.item(idx) : " + err;
        }
    }
</script>
<span id="span1"></span>
<span id="span2"></span>
<div id="info"></div>

经过测试,各浏览器都支持这种方式。

NodeList.namedItem(id)

测试用例代码:

XML/HTML code ?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script type="text/javascript">
    window.onload = function() {
        var spans = document.getElementsByTagName("span");
        try {
            var span2 = spans.namedItem("span2");
            document.getElementById("info").innerHTML = "NodeList.namedItem(name).id: " + span2.id;
        } catch(err) {
            document.getElementById("info").innerHTML = "NodeList.namedItem(name) : " + err;
        }
    }
</script>
<span id="span1"></span>
<span id="span2"></span>
<div id="info"></div>

Chrome和Safari不支持此方法,报错。
其他浏览器输出:NodeList.namedItem(id).id: span2

NodeList.namedItem(name)

测试用例代码:

XML/HTML code ?
1
2
3
4
5
6
7
8
9
10
11
12
13
<script type="text/javascript">
    window.onload = function() {
       var inputs = document.getElementsByTagName("input");
       var input_1 = inputs.namedItem("input1");
       document.getElementById("info").innerHTML += "inputs.namedItem(name).id : " + input_1.id+
               "<br/>inputs.namedItem(name).length : " + input_1.length;
    }
</script>
<input id="ipt1" name="input1">
<input id="ipt2" name="input1">
<input id="ipt3" name="input3">
<div id="info"></div>

Chrome 和 Safari 不支持这个方法。
Firefox、 Opera和IE都支持,但存在差异,情况跟NodeList[name]相同。

使用document.getElementsByTagName()的误差

在利用getElementsByTagName()方法取同一类对象时,浏览器插件生成的标签也会被计算在内。例如,在document.getElementsByTagName("div")的返回值中,包括Firebug插件的div标签。所以,如果利用index取值,可能会跟预想的结果不同。

总结

这个方法真不让人省心啊,既然兼容性问题这么多,那么,应该怎样避免此类问题的发生呢?其实,很简单,用上面表里,所有浏览器都支持的方法就好。少用 index 取元素,不够准确。另外,没有特殊需求而仅仅为了获取元素,请使用document.getElmentById()。

getElementsByTagName相关推荐

  1. 关于querySelector 和 document.getElementsByTagName 选中集合问题

    本文解决的问题是 :运用for..of..循环时,edge浏览器报Object doesn't support property or method 'symbol.iterator'问题 以及 符号 ...

  2. HTML DOM getElementsByTagName() 方法

    定义和用法 getElementsByTagName() 方法可返回带有指定标签名的对象的集合. 语法 document.getElementsByTagName(tagname) 说明 getEle ...

  3. document.getElementsByTagName()方法的返回值

    document.getelementsbytagname()方法的返回值 /* document.getelementsbytagname()方法的返回值中取出某个特定的元素.一开始以为它的返回值是 ...

  4. js 取值 getElementsByTagName,getElementsByName

    getElementsByTagName,getElementsByName 获取的值是数组的所以用[0][1]引用 1 <select multiple size="2"& ...

  5. getElementById() getElementsByName() getElementsByTagName()

    http://www.cnblogs.com/winner/archive/2007/03/28/593028.html 1.getElementById() getElementById()可以访问 ...

  6. 获取表单对象,得三种方法getElementById(), getElementsByName(), and getElementsByTagName() 和用法...

    今天碰到了翻页不好用的问题,检查一下发现没有表单,加上去就好了,发现获取某个对象值的方法有很多,但是使用哪一个才是正规的途径那,问了同事,得出结论如下:   document.表单名称.对象名称.属性 ...

  7. (转)getElementByID getElementsByName getElementsByTagName用法详解

    (转)getElementByID getElementsByName getElementsByTagName用法详解 getElementByID getElementsByName getEle ...

  8. getElementByID() getElementsByName() getElementsByTagName()的区别 .

    getElementByID() getElementsByName() getElementsByTagName()的区别 Web标准下可以通过getElementById(), getElemen ...

  9. DOM的​getElementById() 和 getElementsByTagName() 方法

    DOM查找并访问节点getElementById() 和 getElementsByTagName() 方法 可查找整个 HTML 文档中的任何 HTML 元素,getElementById() 无法 ...

最新文章

  1. 信号量Semaphore一篇文章叫你明白
  2. 奇怪-正则匹配的test函数
  3. 马踏棋盘算法(骑士周游)
  4. 交换机该选择千兆还是百兆的呢?
  5. 竞赛图 计算机网络 应用题,我校学子获2020年“中国高校计算机大赛-网络技术挑战赛”全国总决赛一等奖(图)...
  6. 【Python CheckiO 题解】The Most Numbers
  7. python面试题总结(2)--编码规范
  8. 简述python的安装过程_python3+ selenium3开发环境搭建-手把手教你安装python(详细)...
  9. 面试问题:Spring实现AOP的方式
  10. python return返回值_Python return语句 函数返回值
  11. Spring入门(1)
  12. 人工势场法matlab讲解_【机器人路径规划】人工势场法
  13. SpringBoot项目中快速集成腾讯云短信服务SDK实现手机验证码功能
  14. 原生js获取屏幕高度
  15. linux添加凤凰引导,凤凰系统率先升级内核到Linux4.9
  16. *使用phpspider -- PHP蜘蛛爬虫框架来爬取数据
  17. Mongodb分片学习
  18. Win10 AMD610显卡驱动安装出现错误206安装失败
  19. smartbi连接mysql数据库_Smartbi_V9配置MySQL8作为知识库
  20. python+django大学教室自习室预约管理系统

热门文章

  1. 【开发环境】安装 Visual Studio Code 开发环境 ( 下载 Visual Studio Code 安装器 | Visual Studio Code )
  2. 【Java 并发编程】线程池机制 ( 线程池状态分析 | 线程池状态转换 | RUNNING | SHUTDOWN | STOP | TIDYING | TERMINATED )
  3. 【Android FFMPEG 开发】Android 中使用 FFMPEG 对 MP3 文件进行混音操作
  4. 【OpenGL】十五、OpenGL 绘制三角形 ( 绘制 GL_TRIANGLE_FAN 三角形扇 )
  5. 【Android 安全】DEX 加密 ( Application 替换 | 获取 ContextImpl、ActivityThread、LoadedApk 类型对象 | 源码分析 )
  6. 【Android 安全】DEX 加密 ( Proguard 简介 | Proguard 相关网址 | Proguard 混淆配置 )
  7. 网络基础 + 简易服务端和客户端
  8. Shell脚本基本命令4
  9. java对象 Java中 VO、 PO、DO、DTO、 BO、 QO、DAO、POJO的概念
  10. C#垃圾回收(GC)