zoukankan      html  css  js  c++  java
  • 原生DOM探究 -- NodeList v.s. HTMLCollection

    涉及获取元素的主要API

    在获取原生DOM元素的时候,主要涉及这几个DOM API(链接为Living Standard):

    注:计划取代NodeListHTMLCollectionElements目前并无广泛实现

    基础知识 -- NodeList v.s. HTMLCollection

    在不同版本的浏览器中,如果调用获取多元素的DOM方法(getElement...()),有的会得到NodeList(多为旧浏览器),有的会得到HTMLCollection(多为新浏览器)。使用Node Interface的方法,如childNodes,得到的通常是NodeList,而使用其他Interface的方法,又有可能得到HTMLCollection。所以有必要了解一下这两者的区别。

    关于这两个类型的差异,在Stackoverflow上有一个不错的问答

    其实,只要先看看Living Standard中这两个类型的IDL,便能猜出大概了。NodeList的IDL如下:

    interface NodeList {
      getter Node? item(unsigned long index);
      readonly attribute unsigned long length;
      iterable<Node>;
    };

    HTMLCollection的IDL如下:

    interface HTMLCollection {
      readonly attribute unsigned long length;
      getter Element? item(unsigned long index);
      getter Element? namedItem(DOMString name);
    };

    相同点:

    1. 它们都有length属性
    2. 都有元素的getter,叫做item

    不同点:

    1. NodeList的元素是Node,HTMLCollection的元素是Element

      Element继承自Node,是Node一种,在HTML中,它一般是HTML元素(比如<p><a>之类的标签创建出来的对象)。而Node作为父类,除了Element还有一些其他子类,比如HTML元素内的文本对应的Text,文档对应的Document,注释对应的Comment

      HTMLCollection里,只有Element,而NodeList里可以有ElementTextComment等多种元素。按说如果获取元素返回的列表里只有Element,那这两种类没多大区别,但事实上很多时候浏览器会将解析HTML文本时得到的TextComment一并放进列表里放回。比如说下面这一段代码

      <div>
          <!-- Comment -->
          <p>This is Some Text</p>
      </div>

      若将这个div的子元素放在列表里返回,那么如果是作为NodeList返回,浏览器最多可以给这个列表5个元素(不同浏览器可能不同)

      1. 一个<div>和注释间的断行和空格(或tab)作为text node(没错,标签之间的空白符号也可以被解析为text node)
      2. 注释作为comment node
      3. 注释和<p>之间的断行和空格(或tab)作为text node
      4. p作为element
      5. </p></div>之间的断行和空格(或tab)作为text node

      因此NodeList里可能会有很多一般DOM操作不需要的text node和comment node需要处理。而HTMLCollection则简单多了,只有<p>这一个元素,这也是比较符合大多数人直觉的结果。

    2. HTMLCollection还有一个namedItem方法,可以快速获取其中元素。假设有这样一段HTML:

      <div>
          <!-- Comment -->
          <p>This is Some Text</p>
          <img name="test" src="test.jpg">
      </div>

      那么假设得到了这个div的子元素构成的HTMLCollection,叫做list,那么使用list.namedItem("test")就可以直接得到里面的img元素。

      查找顺序参考Living Standard,但是在现实中不是所有浏览器都遵循标准。比如标准规定如果有多个拥有相同id或者name的元素,只要返回第一个,但chrome和opera会将它们放在一个HTMLCollection或者NodeList里一并返回,参见MDN

    从IDL看不出来的还有如下几点

    1. 这两个类都是“live”的。对其中元素进行操作,会实时反映到DOM中(也因此如果一次性直接在这类列表上进行多个DOM操作的话,带来的开销会很大)。
    2. itemnamedItem都可以通过[]的缩写进行调用,有的浏览器还支持用()的缩写进行调用(也就是可以list[index]list[key]或者list(index)list(key)),以及直接用dot notation调用namedItem(比如list.key)。
    3. 部分浏览器支持对NodeList调用namedItem或间接通过[]()、dot notation来调用namedItem,但由于各浏览器支持不同,最好不对NodeList做这种操作。
    4. IE8及以下版本浏览器中,注释属于HTMLCommentElement,算作Element,因此会出现在HTMLCollection里。
  • 相关阅读:
    HDU 2639 Bone Collector II (01背包,第k解)
    POJ 2184 Cow Exhibition 奶牛展(01背包,变形)
    hihoCoder #1165 : 益智游戏 (挑战赛11 B题)
    UVA 562 Dividing coins 分硬币(01背包,简单变形)
    POJ Charm Bracelet 挑饰品 (常规01背包)
    hiho一下 第四十四周 博弈游戏·Nim游戏(直接公式解)
    UVA 624 CD(01背包,要记录路径)
    118 Pascal's Triangle 帕斯卡三角形 杨辉三角形
    117 Populating Next Right Pointers in Each Node II 每个节点的右向指针 II
    116 Populating Next Right Pointers in Each Node 每个节点的右向指针
  • 原文地址:https://www.cnblogs.com/joyeecheung/p/4067927.html
Copyright © 2011-2022 走看看