跟随标准与Webkit源码探究DOM -- 获取元素之getElementsByTagName
按照标签名获取元素 -- getElementsByTagName
标准
- DOM 1在
Element
和Document
两个interface中均有定义,原型NodeList getElementsByTagName(in DOMString tagname)
,指明按照先序遍历遇到的顺序排列,不会抛出任何异常,参数"*"
返回对应document或者element下所有元素。注意这里指明返回的是一个live的仅含有Element
的NodeList
。 - DOM 2里定义仍在
Element
和Document
,增加了带namespace的NodeList getElementsByTagNameNS(in DOMString namespaceURI, in DOMString localName)
(Element
,Document
),引入了localName
的概念(只有ELEMENT_NODE
和ATTRIBUTE_NODE
才能有)。 - DOM 3(
Document
,Element
)特别声明XML应当对标签名的大小写敏感,非XML则依照文档类型自己对待大小写的风格来决定是否敏感。实际上浏览器对HTML都会先将标签转统一换成成小写后再去匹配,所以只能匹配到实际标签名为小写的元素。 - WHATWG (
Document
,Element
)将返回类型修改为了HTMLCollection
,并解释了通过localName
产生HTMLCollection
的算法。注意算法的第二步实际上规定了在非HTML文档里,标签名大小写敏感;而在HTML文档里,任何大小写的标签都会被统一转换成小写后再去匹配,所以只能匹配到实际标签名为小写的元素。 - DOM 4(Document,Element) 目前与 WHATWG 基本一致
DOM Tree Accessors
DOM 1 与 DOM 2 的 HTMLDocument
interface 里定义了一系列"DOM Tree Accessors"
readonly attribute HTMLCollection images
readonly attribute HTMLCollection applets
readonly attribute HTMLCollection links
readonly attribute HTMLCollection forms
readonly attribute HTMLCollection anchors
attribute HTMLElement body
这意味着在HTML文档里可以用document.images
获得所有<img>
元素,用document.links
获取所有带有href
属性的<a>
元素,用document.links
获取所有带有name
属性的<a>
元素,用document.forms
获取所有<form>
元素。另外获取<body>
可以使用document.body
。
自 HTML5(W3C,WHATWG)开始还定义了document.head
,删去了document.anchors
,增加了获取<embed>
的document.embeds
和目前与之相同的document.plugins
,以及获取<script>
的document.scripts
。
自 DOM 1 便在Document
定义了document.documentElement
来获取根元素并保留至今,在HTML文档里即<html>
元素。
兼容性
- IE 5.5 不支持
*
作为参数获取所有元素。IE6以上的IE以及各大浏览器均按照标准实现了getElementsByTagName
。 - 虽然
document.scripts
,document.embeds
和document.plugins
直到HTML5才标准化,不过各版本IE和其他浏览器的现行版本都支持 document.head
需要IE9+才支持。其他DOM Tree Accessor基本在各版本IE和现行的浏览器里都有支持。
Webkit 代码分析
类似getElementsByName
,getElementsByTagName
在ContainerNode
里实现。由于标准里对XML的特殊规定,这里会依据文档类型,换用TagNodeList
或者HTMLTagNodeList
作为NodeListsNodeData::addCacheWithAtomicName<>
的template specialization(参见WebCore/dom/ContainerNode.cpp)。
TagNodeList
实现的elementMatches
是:
if (m_localName != starAtom && m_localName != element.localName())
return false;
return m_namespaceURI == starAtom || m_namespaceURI == element.namespaceURI();
这里starAtom
就是标准里说的*
。先比对localName是否相符或为*
,然后比对namespaceURI是否相符或为*
。由于没有大小写转换步骤,所以遵循标准,是大小写敏感的。注意这里比对namespaceURI的步骤相对于getElementsByTagName
是多余的,之所以加上是因为getElementsByTagNameNS
也用TagNodeList
,这样就可以偷懒不用再多写一个比对namespaceURI的版本。不过getElementsByTagNameNS
用的其实是addCacheWithQualifiedName
而不是addCacheWithAtomicName
,其实addCacheWithQualifiedName
和addCacheWithAtomicName
的不同也就是它拿TagNodeList
直接提前做好了template specification而已(参见WebCore/dom/NodeRareData.h)
HTMLTagNodeList
实现的elementMatches
是:
if (m_localName == starAtom)
return true;
const AtomicString& localName = element.isHTMLElement() ? m_loweredLocalName : m_localName;
return localName == element.localName();
按照标准所说,如果被比对的元素是HTML namespace里的,转换为小写再比较。注意这里没有比对namespaceURI,毕竟getElementsByTagNameNS
不用它(标准里没有指明getElementsByTagNameNS
需要转换大小写,所以用TagNodeList
那个大小写敏感的过滤足矣)。
跟随标准与Webkit源码探究DOM -- 获取元素之getElementsByTagName的更多相关文章
- 跟随标准与Webkit源码探究DOM -- 获取元素之querySelector,querySelectorAll
使用CSS选择器获取元素 -- querySelector,querySelectorAll(HTML5) 标准 W3C Selector API Level 1为Document,DocumentF ...
- 跟随标准与Webkit源码探究DOM -- 获取元素之getElementsByClassName
按照类名获取元素 -- getElementsByClassName(HTML5) 标准 WHATWG 在Document与Element上均有定义,原型 HTMLCollection getElem ...
- 跟随标准与Webkit源码探究DOM -- 获取元素之getElementById
按照ID获取元素 -- getElementById 标准 DOM 1,定义在HTMLDocument Interface 中,原型Element getElementById(in DOMStrin ...
- 跟随标准与Webkit源码探究DOM -- 获取元素之getElementsByName
按照name属性获取多元素 -- getElementsByName 标准 DOM 1 定义在HTMLDocument Interface 中,原型NodeList getElementsByName ...
- ConcurrentHashMap源码探究 (JDK 1.8)
很早就知道在多线程环境中,HashMap不安全,应该使用ConcurrentHashMap等并发安全的容器代替,对于ConcurrentHashMap也有一定的了解,但是由于没有深入到源码层面,很多理 ...
- Vue源码探究-虚拟DOM的渲染
Vue源码探究-虚拟DOM的渲染 在虚拟节点的实现一篇中,除了知道了 VNode 类的实现之外,还简要地整理了一下DOM渲染的路径.在这一篇中,主要来分析一下两条路径的具体实现代码. 按照创建 Vue ...
- Vue源码探究-全局API
Vue源码探究-全局API 本篇代码位于vue/src/core/global-api/ Vue暴露了一些全局API来强化功能开发,API的使用示例官网上都有说明,无需多言.这里主要来看一下全局API ...
- Vue源码探究-事件系统
Vue源码探究-事件系统 本篇代码位于vue/src/core/instance/events.js 紧跟着生命周期之后的就是继续初始化事件相关的属性和方法.整个事件系统的代码相对其他模块来说非常简短 ...
- Vue源码探究-状态初始化
Vue源码探究-状态初始化 Vue源码探究-源码文件组织 Vue源码探究-虚拟DOM的渲染 本篇代码位于vue/src/core/instance/state.js 继续随着核心类的初始化展开探索其他 ...
随机推荐
- python os&shutil 文件操作
python os&shutil 文件操作 # os 模块 os.sep 可以取代操作系统特定的路径分隔符.windows下为 '\\' os.name 字符串指示你正在使用的平台.比如对于W ...
- [51单片机] EEPROM 24c02 [I2C代码封装-保存实现流水灯]
这里把EEPROM 24c02封装起来,今后可以直接调用,其连线方式为:SDA-P2.1;SCL-P2.0;WP-VCC >_<:i2c.c /*--------------------- ...
- atitit.RESTful服务的概览and框架选型
atitit.RESTful服务的概览and框架选型 1. REST基础概念: 1 2. URL说明: 1 3. 1 4. RESTful框架选型 2 1. spring mvc( recomm) ...
- paip . 解决spring No unique bean of type [com.mijie.homi.search.service.index.MoodUserIndexService]
paip . 解决spring No unique bean of type [com.mijie.homi.search.service.index.MoodUserIndexService] ...
- Html+css 练习写页面发现的错误及解决办法。
最近开始模仿写一些静态页面,今天模仿的是中华咨询网.写了一个简单的js(功能:当鼠标hover一级菜单的时候,设置二级菜单为显示,当鼠标hover二级菜单的选项时候,二级菜单不收回.当鼠标移出菜单一级 ...
- ArrayList/Vector的原理、线程安全和迭代Fail-Fast
疑问 * ArrayList是非线程非安全的,具体是指什么?具体会产生什么问题?* ArrayList的内部原理是什么?为什么可以动态扩容?* Vector是线程安全的,具体是如何实现的?为什么不再推 ...
- Python 3 数值计算
Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:43:06) [MSC v.1600 32 bit (Intel)] on win32Type & ...
- Task中的异常处理
最简单的方式 var t = new Task(() => { throw new Exception("unknow excption"); }); t.Start(); ...
- HTTP请求报文和HTTP响应报文(转)
原文地址:http://blog.csdn.net/zhangliang_571/article/details/23508953 HTTP报文是面向文本的,报文中的每一个字段都是一些ASCII码串, ...
- netfilter分析
转自:http://blog.sina.com.cn/s/blog_a31ff26901013n07.html 一.概述 1. Netfilter/IPTables框架简介 Netfilter/IPT ...