跟随标准与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 imagesreadonly attribute HTMLCollection appletsreadonly attribute HTMLCollection linksreadonly attribute HTMLCollection formsreadonly attribute HTMLCollection anchorsattribute 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 继续随着核心类的初始化展开探索其他 ...
随机推荐
- atitit.提升软件开发的效率and 质量的那些强大概念and方法总结
atitit.提升软件开发的效率and 质量的那些强大概念and方法总结 1. 主流编程中三个最糟糕的问题 1 1.1. 从理解问题后到实现的时间很长 1 1.2. 理解和维护代码 2 1.3. 学 ...
- HTML+CSS提升小实战
1 <html> 2 <head> 3 <meta http-equiv="Content-Type" content="text/html ...
- Proxy模式:管理第三方API
软件中的Barrier. 数据从程序移到DB中时,要跨越数据库的Barrier.消息从一个PC到另一个PC时,要跨越网络Barrier. 跨越可能是复杂的,很可能处理Barrier的Code会多于处理 ...
- Linux内核启动分析过程-《Linux内核分析》week3作业
环境搭建 环境的搭建参考课件,主要就是编译内核源码和生成镜像 start_kernel 从start_kernel开始,才真正进入了Linux内核的启动过程.我们可以把start_kernel看做平时 ...
- AsyncTask实现多任务多线程断点续传下载
这篇博客是AsyncTask下载系列的最后一篇文章,前面写了关于断点续传的和多线程下载的博客,这篇是在前两篇的基础上面实现的,有兴趣的可以去看下. 一.AsyncTask实现断点续传 二.AsyncT ...
- FTP客户端上传下载Demo实现
1.第一次感觉MS也有这么难用的MFC类: 2.CFtpFileFind类只能实例化一个,多个实例同时查找会出错(因此下载时不能递归),采用队列存储目录再依次下载: 3.本程序支持文件夹嵌套上传下载: ...
- 搭建自己的OpenWrt开发环境
1. 安装环境Linux系统,如果在CentOS上操作,需安装如下依赖包:yum install binutils bzip2 gawk gcc gcc-c++ gettext makencurse ...
- <后会无期>经典影评
先说明是转载,任何不同意见请对原作者表达,楼主不作任何回应,楼主影商极低,楼主觉得这二十几年来看的最好的电影是<一代宗师>,楼主只是觉得这篇影评精彩才发布上来让更多的人看到.原作者意见和楼 ...
- 使用React、Node.js、MongoDB、Socket.IO开发一个角色投票应用的学习过程(三)
这几篇都是我原来首发在 segmentfault 上的地址:https://segmentfault.com/a/1190000005040834 突然想起来我这个博客冷落了好多年了,也该更新一下,呵 ...
- 微信公众平台开发视频教程-03-获取Access Token和获取微信服务器IP,添加微信菜单
1 获取access token 此token是以后每次调用微信接口都会带上的票据,token是公众号全局唯一票据,在调用其他接口之前都需要先得到token,taoken长度至少512个字符,通常用s ...