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

按照标签名获取元素 -- 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那个大小写敏感的过滤足矣)。

时间: 2024-10-09 05:31:45

跟随标准与Webkit源码探究DOM -- 获取元素之getElementsByTagName的相关文章

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

按照ID获取元素 -- getElementById 标准 DOM 1,定义在HTMLDocument Interface 中,原型Element getElementById(in DOMString elementId),当不存在拥有对应ID的元素时返回null,该方法不会抛出任何异常. DOM 2,移动到了Document(原HTMLDocument的Parent Interface),原型不变. DOM 3 特别声明浏览器应当使用Attr.isId判断 Attr 是否为 ID,同时加了一

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

按照类名获取元素 -- getElementsByClassName(HTML5) 标准 WHATWG 在Document与Element上均有定义,原型 HTMLCollection getElementsByClassName(DOMString classNames),并定义了匹配算法和类名的提取算法,注意这里是先从参数里提取出类名作为一个set,然后再开始匹配的.其中指明了在quirks mode下类名大小写不敏感,否则大小写敏感 DOM 4(Document,Element )基本和W

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

使用CSS选择器获取元素 -- querySelector,querySelectorAll(HTML5) 标准 W3C Selector API Level 1为Document,DocumentFragment和Element追加了querySelector和querySelctorAll,原型为Element? querySelector(DOMString selectors)和 NodeList querySelectorAll(DOMString selectors),说明了匹配的算

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

按照name属性获取多元素 -- getElementsByName 标准 DOM 1 定义在HTMLDocument Interface 中,原型NodeList getElementsByName(in DOMString elementName),该方法不会抛出任何异常. DOM 2依然定义在HTMLDocument,原型不变,但是新增说明在 HTML4.0 里搜索范围为所有元素,而 XHTML 1.0 里搜索范围缩小到表单元素 DOM 3没有 DOM HTML 的标准,沿袭 DOM 2(

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

Vue源码探究-虚拟DOM的渲染 在虚拟节点的实现一篇中,除了知道了 VNode 类的实现之外,还简要地整理了一下DOM渲染的路径.在这一篇中,主要来分析一下两条路径的具体实现代码. 按照创建 Vue 实例后的一般执行流程,首先来看看实例初始化时对渲染模块的初始处理.这也是开始 mount 路径的前一步.初始包括两部分,一是向 Vue 类原型对象上挂载渲染相关的方法,而是初始化渲染相关的属性. 渲染的初始化 下面代码位于vue/src/core/instance/render.js 相关属性初始

Vue源码探究-事件系统

Vue源码探究-事件系统 本篇代码位于vue/src/core/instance/events.js 紧跟着生命周期之后的就是继续初始化事件相关的属性和方法.整个事件系统的代码相对其他模块来说非常简短,分几个部分来详细看看它的具体实现. 头部引用 import { tip, toArray, hyphenate, handleError, formatComponentName } from '../util/index' import { updateListeners } from '../

windows7下cygwin+vs2013编译webkit源码

先下载源码和其他依赖,然后准备cygwin的环境,安装vs2013,最后编译即可.网上没有能直接用于最新版本源码编译的教程,所以我在编译过程中也遇到了很多坑.回过头来看,这些坑都是可以避免的,想要自己尝试编译的同学,可以根据本文快速的实现自己编译webkit(~除去下载文件的时间,15分钟准备环境,1小时编译完成). 下载最近源码 最近的下载版本和源码在这里: http://nightly.webkit.org/ 我使用的源码是这个版本built on 13 October 2014 and i

Android源码探究之AsyncTask 源码解析

AsyncTask源码使用 Api23版本,后面介绍和以前版本改动不同之处. 先看使用: /** * 下面四个方法中除了doInBackground方法在子线程,其他方法都在主线程执行 * String 表示传进来的参数, * Void 表示子线程执行过程中对主线程进行反馈所传的数据类型 * Integer 子线程执行的结果 */ private class MyAsyncTask extends AsyncTask<String,Void,Integer>{ @Override protec

Flink 源码解析 —— 如何获取 ExecutionGraph ?

https://t.zsxq.com/UnA2jIi 博客 1.Flink 从0到1学习 -- Apache Flink 介绍 2.Flink 从0到1学习 -- Mac 上搭建 Flink 1.6.0 环境并构建运行简单程序入门 3.Flink 从0到1学习 -- Flink 配置文件详解 4.Flink 从0到1学习 -- Data Source 介绍 5.Flink 从0到1学习 -- 如何自定义 Data Source ? 6.Flink 从0到1学习 -- Data Sink 介绍 7