zoukankan      html  css  js  c++  java
  • 跟随标准与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那个大小写敏感的过滤足矣)。

  • 相关阅读:
    安装Hadoop
    爬取全部的校园新闻
    理解爬虫原理
    复合数据类型,英文词频统计
    字符串操作、文件操作,英文词频统计预处理
    了解大数据的特点、来源与数据呈现方式
    四则运算升级
    初级四则运算
    分布式版本控制系统Git的安装与使用
    作业——12 hadoop大作业
  • 原文地址:https://www.cnblogs.com/joyeecheung/p/4115426.html
Copyright © 2011-2022 走看看