跟随标准与Webkit源码探究DOM -- 获取元素之getElementsByTagName
2014-11-22 17:35
483 查看
按照标签名获取元素 -- 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 的HTMLDocumentinterface 里定义了一系列"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 -- 获取元素之getElementsByName
- 跟随标准与Webkit源码探究DOM -- 获取元素之getElementsByClassName
- 跟随标准与Webkit源码探究DOM -- 获取元素之getElementById
- 跟随标准与Webkit源码探究DOM -- 获取元素之querySelector,querySelectorAll
- IE中getElementsByTagName无法获取元素BUG
- JS基础——getElementsByTagName获取元素
- getElementsByTagName是根据标签名获取元素
- JS中获取元素使用getElementByID()、getElementsByName()、getElementsByTagName()的用法和区别
- 对getElementsByTagName("*")获取全部元素的总结
- 获取dom document.getElementsByTagName('*')
- 对getElementsByTagName("*")获取全部元素的总结
- getElementById;getElementsByName;getElementsByTagName获取对象的区别
- c#中从html中使用GetElementsByTagName来获取数据的例子
- SCRIPT5007: 无法获取属性“getElementsByTagName”的值: 对象为 null 或未定
- DOM方法(getElementById, getElementsByTagName, getAttribute, setAttribute)
- php版getElementsByTagName , php版根据标签名获取 标签节点列表.模拟javascript的getElementsByTagName函数
- Javascript下获取对象引用的两种方法之getElementsByTagName
- 获取表单对象,得三种方法getElementById(), getElementsByName(), and getElementsByTagName() 和用法
- getElementById;getElementsByName;getElementsByTagName获取对象的区别
- js 获取class的元素的方法 以及创建方法getElementsByClassName