按照标签名获取元素 -- getElementsByTagName

标准

  • DOM 1在ElementDocument两个interface中均有定义,原型NodeList getElementsByTagName(in DOMString tagname),指明按照先序遍历遇到的顺序排列,不会抛出任何异常,参数"*"返回对应document或者element下所有元素。注意这里指明返回的是一个live的仅含有ElementNodeList
  • DOM 2里定义仍在ElementDocument,增加了带namespace的NodeList getElementsByTagNameNS(in DOMString namespaceURI, in DOMString localName)ElementDocument),引入了localName的概念(只有ELEMENT_NODEATTRIBUTE_NODE才能有)。
  • DOM 3(DocumentElement)特别声明XML应当对标签名的大小写敏感,非XML则依照文档类型自己对待大小写的风格来决定是否敏感。实际上浏览器对HTML都会先将标签转统一换成成小写后再去匹配,所以只能匹配到实际标签名为小写的元素。
  • WHATWG (Document ,Element)将返回类型修改为了HTMLCollection,并解释了通过localName产生HTMLCollection的算法。注意算法的第二步实际上规定了在非HTML文档里,标签名大小写敏感;而在HTML文档里,任何大小写的标签都会被统一转换成小写后再去匹配,所以只能匹配到实际标签名为小写的元素。
  • DOM 4(DocumentElement) 目前与 WHATWG 基本一致

DOM Tree Accessors

DOM 1DOM 2HTMLDocument 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(W3CWHATWG)开始还定义了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.scriptsdocument.embedsdocument.plugins直到HTML5才标准化,不过各版本IE和其他浏览器的现行版本都支持
  • document.head需要IE9+才支持。其他DOM Tree Accessor基本在各版本IE和现行的浏览器里都有支持。

Webkit 代码分析

类似getElementsByNamegetElementsByTagNameContainerNode里实现。由于标准里对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,其实addCacheWithQualifiedNameaddCacheWithAtomicName的不同也就是它拿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的更多相关文章

  1. 跟随标准与Webkit源码探究DOM -- 获取元素之querySelector,querySelectorAll

    使用CSS选择器获取元素 -- querySelector,querySelectorAll(HTML5) 标准 W3C Selector API Level 1为Document,DocumentF ...

  2. 跟随标准与Webkit源码探究DOM -- 获取元素之getElementsByClassName

    按照类名获取元素 -- getElementsByClassName(HTML5) 标准 WHATWG 在Document与Element上均有定义,原型 HTMLCollection getElem ...

  3. 跟随标准与Webkit源码探究DOM -- 获取元素之getElementById

    按照ID获取元素 -- getElementById 标准 DOM 1,定义在HTMLDocument Interface 中,原型Element getElementById(in DOMStrin ...

  4. 跟随标准与Webkit源码探究DOM -- 获取元素之getElementsByName

    按照name属性获取多元素 -- getElementsByName 标准 DOM 1 定义在HTMLDocument Interface 中,原型NodeList getElementsByName ...

  5. ConcurrentHashMap源码探究 (JDK 1.8)

    很早就知道在多线程环境中,HashMap不安全,应该使用ConcurrentHashMap等并发安全的容器代替,对于ConcurrentHashMap也有一定的了解,但是由于没有深入到源码层面,很多理 ...

  6. Vue源码探究-虚拟DOM的渲染

    Vue源码探究-虚拟DOM的渲染 在虚拟节点的实现一篇中,除了知道了 VNode 类的实现之外,还简要地整理了一下DOM渲染的路径.在这一篇中,主要来分析一下两条路径的具体实现代码. 按照创建 Vue ...

  7. Vue源码探究-全局API

    Vue源码探究-全局API 本篇代码位于vue/src/core/global-api/ Vue暴露了一些全局API来强化功能开发,API的使用示例官网上都有说明,无需多言.这里主要来看一下全局API ...

  8. Vue源码探究-事件系统

    Vue源码探究-事件系统 本篇代码位于vue/src/core/instance/events.js 紧跟着生命周期之后的就是继续初始化事件相关的属性和方法.整个事件系统的代码相对其他模块来说非常简短 ...

  9. Vue源码探究-状态初始化

    Vue源码探究-状态初始化 Vue源码探究-源码文件组织 Vue源码探究-虚拟DOM的渲染 本篇代码位于vue/src/core/instance/state.js 继续随着核心类的初始化展开探索其他 ...

随机推荐

  1. HTTP权威指南阅读笔记五:Web服务器

    Web服务器会做些什么: 1.建产连接:接受一个客户端连接,或者如果不希望与这个客户端建立连接,就将其关闭. 1)处理新连接 2)客户端主机名识别 3)通过ident确定客户端用户 ident在组织内 ...

  2. [BTS] System.Xml.Schema.XmlSchemaException: The complexType has already been declared when generate IDoc schema.

    I use wcf-sap adapter for generate the schema of IDoc that named "YHREMPMASTER". but throw ...

  3. Backbone入门——开发第一个Backbone页面

    1. 功能描述在新建的html页面中,通过导入的backbone文件搭建一个简单的mvc结构.当用户进入该页时,id号为“divTip”的<div>元素中将显示“hello,backbon ...

  4. SVG的路径动画效果

    使用SVG animateMotion实现的一个动画路径效果,相关代码如下. 在线调试唯一地址:http://www.gbtags.com/gb/debug/c88f4099-5056-4ad7-af ...

  5. crossplatform---Nodejs in Visual Studio Code 06.新建Module

    1.开始 Node.js:https://nodejs.org 2.Moudle js编程中,由于大家可以直接在全局作用域中编写代码,使开发人员可以很容易的新建一个全局变量或这全局模块,这些全局变量或 ...

  6. paip.获取proxool的配置 xml读取通过jdk xml 初始化c3c0在代码中总结

    paip.获取proxool的配置  xml读取通过jdk xml 初始化c3c0在代码中  xml读取通过jdk xml 初始化c3c0在代码中.. ... 作者Attilax  艾龙,  EMAI ...

  7. java异常处理——题

    1.建立exception包,编写TestException.java程序,主方法中有以下代码,确定其中可能出现的异常,进行捕获处理. public class YiChang { public st ...

  8. iOS开发---百度地图配置流程,2.6.0 版本 支持64位

      1.首先需要在百度地图下载最新SDK:地址: http://developer.baidu.com/map/index.php?title=iossdk/sdkiosdev-download 2. ...

  9. 微信小程序笔记(二)

    微信小程序环境搭建与开发工具介绍 2-1 开篇介绍及下载工具 1.开发工具下载地址:   http://t.cn/RVKH0HS 2.下载安装对应版本:win32,win64,mac; 2-2 小程序 ...

  10. 解决pageControl页面设置无效问题

    废话不多说,先上代码 1.添加pageViewControl - (void)addPageControl { UIPageControl *pageControl = [[UIPageControl ...