DOM——《JavaScript高级程序设计》笔记

DOM(文档对象模型)

  @针对HTML和XML文档的一个API,为基本的文档结构及查询提供接口
  @IE中的DOM都是以COM对象的形式实现的,故IE中的DOM对象于原生JavaScript对象的行为或活动特点有差异。

  10.1节点层次

    @DOM能够将任何HTML或XML文档庙会成一个由多层节点构成的结构。
    @每个文档只能有一个文档元素,在HTML页面中,文档元素为<html>元素。【根节点为Document,最外层元素为文档元素html】
    @HTML元素通过元素节点表示,特性(attribute)通过特性节点表示,文档类型通过文档类型节点表示,注释通过注释节点表示。

    10.1.1 Node类型

      @DOM1级定义了Node接口,由DOM中的所有节点类型实现。除了IE外,JavaScript中的节点都是继承自Node类型。
      @节点类型由Node类型定义的12个数值常量表示:
        Node.ELEMENT_NODE(1);
        Node.ELEMENT_NODE (1)
        Node.ATTRIBUTE_NODE (2)
        Node.TEXT_NODE (3)
        Node.CDATA_SECTION_NODE (4)
        Node.ENTITY_REFERENCE_NODE(5)
        Node.ENTITY_NODE (6)
        Node.PROCESSING_INSTRUCTION_NODE (7)
        Node.COMMENT_NODE (8)
        Node.DOCUMENT_NODE (9)
        Node.DOCUMENT_TYPE_NODE (10)
        Node.DOCUMENT_FRAGMENT_NODE (11)
        Node.NOTATION_NODE (12)
      @通过上面的常量能判断节点的类型,但由于IE没有公开Node类型的构造函数,故应该用数字值进行比较:

if (someNode.nodeType == Node.ELEMENT_NODE){  //在IE中无效
    alert("元素节点");
}

if (someNode.nodeType == 1){  //所有浏览器适应
    alert("元素节点");
}

      ① nodeName 和 nodeValue

        @对于元素节点,nodeName保存元素的标签名,nodeValue值为null。

      ② 节点关系

        每个节点都有一个childNodes属性,保存着一个NodeList对象(一种类数组对象,保存一组有序的节点)。
          @可通过方括号语法item()方法访问NodeList的值,有length属性,但不是Array的实例,而是基于DOM结构动态查询的结果。
          @在IE8-浏览器中,会为空白符创建节点,length属性值会包含空白符节点。

var firstChild = someNode.childNodes[0];
var secondChild = someNode.childNodes.item(1);
var count = someNode.childNodes.length;

           @length属性表示的是访问NodeList那一刻节点的数量。

          @将NodeList对象转换为数组:使用Array.prototype.slice()【IE8及以下无效,需要手动枚举所有成员】

function toArray(){
  var array = null;
  try {
    array = Array.prototype.slice.call(nodes, 0); //针对IE9+等浏览器
  } catch(ex){
    array = new Array();
    for (var i = 0; i < nodes.length; i++) {  //针对IE8-
      array.push(nodes[i]);
    };
  }
  return array;
}

         每个节点都有一个parentNode属性。包含在NodeList列表中的所有节点具有相同的父节点,他们的parentNode指向同个父节点。

        每个节点通过previousSiblingnextSibling属性访问相邻节点。首个节点的previousSibling和末尾节点的nextSibling都是null
          @只有一个子节点时,firstChildlastChild指向同个子节点。没有节点时都为null
          @hasChildNodes()方法在节点包含子节点时返回true。

      ③ 操作节点

        appendChild():1个子节点参数。向NodeList列表末尾添加一个新节点。
          @当传入的节点已经是文档的一部分时,该节点讲过从原点的位置转移到新位置。
        insertBefore():2个参数。在指定节点前插入一个新节点。
          @当指定的节点即第一个参数为null时,insertBefore()和appendChild()执行相同的操作。

//插入后成为最后一个子节点
returnedNode = someNode.insertBefore(newNode,null);
alert(newNode == someNode.lastChild);  //true

//插入后成为第一个子节点
returnedNode = someNode.insertBefore(newNode,firstChild);
alert(returnedNode == newNode );          //true
alert(newNode == someNode.firstChild);  //true

//插入到最后一个子节点前面
returnedNode = someNode.insertBefore(newNode,someNode.lastChild);
alert(newNode == someNode.childNodes[someNode.childNodes.lehgth-2]);  //true

        replaceChild():2个参数。以上述2种不同的是,这个方法会代替原来的节点。
          @插入一个节点时,原节点的所有关系指针都会被代替节点复制过去,但原节点仍在文档中,只是没有了自己的位置。

//替换第一个子节点
var returnedNode = someNode.replaceChild(newNode,someNode.firstChild);
//替换最后一个子节点
returnedNode = someNode.replaceChild(newNode,someNode.lastChild);

        removeChild():1个参数。移除节点。移除的节点成为方法的返回值。
          @同样,移除的节点仍为文档所有,只是没有了自己的位置。

        前面4中操作方法,都需要先取得父节点。使用该4种方法操作不支持子节点的节点时,会导致错误发生。

      ④ 其他方法

        2个所有类型节点都有的方法:cloneNode()normalize()

        cloneNode():1个布尔值参数(表是否执行深复制)。用于创建调用这个方法的节点的一个完全相同的副本。
          参数为true时,执行深复制,即复制节点及其整个子节点树。
          参数为false时,执行浅复制,即只复制节点本身。
          @cloneNode():不会复制DOM节点的JavaScript属性(如事件处理程序),只复制特性。IE则会复制JavaScript属性。

        normalize():用于处理文档树中的文本节点:删除空文本节点 和 合并相邻文本节点。

    10.1.2 Document 类型

      @JavaScript通过Document类型表示文档(HTML或XML)。浏览器中,document是HTMLDocument(继承自Document类型)的一个实例。
      @document对象表示整个HTML页面,是window对象的属性,故可作为全局对象来访问。
        nodeType=9
        nodeName="#document"
        nodeValue、parentNode、ownerDocument = null
        子节点 可能是:DocumentType(最多一个)、Element(最多一个)、ProcessingInstruction 或 Comment。

      ① 文档的子节点

        @访问document子节点的2个快捷方式:documentElement属性 和 通过childNodes列表访问文档元素。

var html = document.documentElement; //取得对<html>的引用

//html的值 与 document.childNodes[0] 和 document.firstChild相同。

        @document对象还有一个body属性,指向<body>元素。
        @Document有一个可能的子节点DocumentType。
          通常将<!DOCTYPE>标签看成一个与文档其他部分不同的实体,可通过doctype属性访问,但该属性兼容性差。

       ② 文档信息

        @作为HTMLDocument的实例,document对象有一些标准Document对象没有的属性。
        @title属性:将<title>元素中的文本,显示在浏览器窗口的标题栏的标签页上。
        @存在请求的HTTP头部的属性:
          URL属性,包含网页完整的URL。 var url = document.URL;
          domain属性,包含页面的域名。
          referrer属性,保存着链接到当前页面的那个页面的URL。没有来源页面时,为空字符串。
          @3个中只有domain可设置,但受安全限制:
            如:URL为aa.bbb.com时,domain只能设为bbb.com;
              URL为www.bbb.com时,domain只能设为bbb.com。
            不能将domain设置为URL不包含的域。
          @跨域:当包含来自其他子域的框架或内嵌框架时,由于安全限制,默认不能与不同子域的页面进行JavaScript通信。
              但通过将彼此的document.domain设置相同值,就能互访对方的JavaScript对象。
            如:主页www.bbb.com,框架内的页面aa.bbb.com,设置彼此的document.domain = "bbb.com";,就能互访。
          @对domain的另一个限制:不能将"松散的"(loose)domain属性 再设置为"紧绷的"(tight)
            如:不能将松散的"bbb.com"设置为紧绷的"aa.bbb.com"。

      ③ 查找元素

        Document类型提供2种方法:getElementById() 和 getElementByTagName()
          getElementById():通过元素的ID引用元素。
            @当页面有多个元素相同ID时,返回文档中第一次出现的元素。
            @在IE7及以下版本中,name值以ID相同的表单元素也会被返回。当name与ID值相同的表单元素位于前面时,后面的“ID元素”不会被返回。
              应该避免表单元素中name属性与其他元素的ID值相同。
          getElementByTagName():接收标签名,返回包含零或多个元素的NodeList。在HTML中,返回一个HTMLCollection对象,一个"动态"集合。
            @通过方括号语法item()方法name值 访问HTMLCollection对象中的项,元素数量通过其length属性取得。
            @HTMLCollection对象的namedItem()方法可通过元素name特性取得集合中的项。
            @对HTMLCollection而言,可向方括号中传入数值或字符串形式的牵引值,
              在后台,对数值牵引就会调用item()方法,对于字符串就会调用namedItem()
          getElementByName():返回给定name特性的所有元素。常用于取得单选按钮。

       ④ 特殊集合

        document.anchors:包含所有带name特性的<a>元素。
        document.links:包含所有带href特性的<a>元素。
        document.forms:包含所有<form>元素。结果同document.getElementByTagName(“form”);
        document.images:包含所有<img>元素

      ⑤ 文档写入

        将输出流写入页面的4个方法:write()、writeln()、opne() 和 close()
          @write()原样写入。writeln()在字符串较为添加一个换行符(\n)。
          @输入"</script>"时,应该添加转义序列,不然会被解释为与外部<script>标签匹配,' "); '会出现在页面中。

document.write("<script type=\"text\javascript\" src=\"file.js\">" + "<\/script>");

          @加载结束后,再调用document.write()输出的内容会重写整个页面

<body>
    <p>This is some content that you won't get to see because it will be overwritten.</p>
    <script type="text/javascript">
        window.onload = function(){
            document.write("Hello world!");
        };
    </script>
</body>
重写页面

          @open()和close()分别打开和关闭输出流。

    10.1.3 Element类型

      @Element节点的子节点可能是:Element、Text、Comment、ProcessingInstruction、CDATASection 或 EntityReference。
      @通过nodeNametagName能访问元素的标签名
      @在HTML中,标签名始终全部大写。在XML中,始终与源代码一致。最好使用toLowerCase()统一转换为小写。

        ① HTML元素

          @所有HTML元素 都由HTMLElement类型或其子类型表示。HTMLElement继承自Element。
          @每个HTML元素的标准特性:
            id元素在文档的唯一标识符、className对应元素的name特性、title附加说明信息、lang元素内容的语言代码、dir语言方向"ltr"/"rtl"。

        var div = null;
        function getValues(){
            if (div == null) {
                div = document.getElementById("myDiv");
            }
            alert(div.id);         //"myDiv"
            alert(div.className);  //"bd"
            alert(div.title);      //"Body text"
            alert(div.lang);       //"en"
            alert(div.dir);        //"ltr"
        }    
        
        function setValues(){
            if (div == null) {
                div = document.getElementById("myDiv");
            }
        
            div.id = "someOtherId";
            div.className = "ft";
            div.title = "Some other text";
            div.lang = "fr";
            div.dir ="rtl";        
        }
HMTL元素 标准特性

        ② 取得特性

          操作DOM的3个方法:getAttribute()、setAttibute()、removeAttribute()

            getAttribute()【应该尽量不用它访问HTML特性】
              @传入的为实际的特性名,故应该用class而不是className。不存在时,返回null。
              @可获取自定义特性(标准HTML语言没有的特性),特性名称不区分大小写。在HTML5规范中,自定义特性应该以“data-”前缀。
                @只有公认特性才会以属性的形式添加到DOM对象中。自定义特性只有在IE中才被创建为属性。

//<div id="myDiv" my_attribute="hello!">Some text</div>

var div = document.getElementById("myDiv");
alert(div.id);                                 //"myDiv"
alert(div.my_special_attribute);   // undefined (IE 返回"hello!")  

              @两类特殊的特性:style属性事件处理程序
                @通过getAttribute()返回CSS文本,通过访问style属性返回一个对象
                @事件句柄中的JS代码通过getAttribute()访问时,返回相应代码的字符串。而在直接访问类似onclick属性时,返回一个函数。
                @在IE7-中两个特性分别返回一个对象和一个函数。

        ③ 设置特性

          setAttitude()
            @通过此方法设置的特性名会被统一转换为小写形式。
            @所有特性都是属性,故可以直接赋值和调用:div.id = "balabala";
              但自定义特性在IE以外的浏览器,为DOM元素添加一个自定义的属性时,该属性不会自动成为元素的特性

div.myColor = "red";
alert(div.getAttibute("myColor"));  //null (IE除外)

               在IE7-中使用上述方法设置class、style属性 和 事件句柄,没有效果。故推荐使用属性来设置特性。

          removeAttitude()【IE6-不支持

        ④ attitude属性【没getAttribute()等方法方便】

          @Element类型是使用attributes属性的唯一一个DOM节点类型。
          @attributes属性包含一个NamedNodeMap集合(类似NodeList)。
            元素的每一个特性都由一个Attr节点表示,Attr节点保存早NameNodeMap对象中。
          @NameNodeMap对象的方法:
            getNamedItem(name):返回nodeName属性等于name的节点。
            removeNamedItem(name):从列表中移除nodeName属性等于name的节点。
            setNamedItem(node):向列表中添加节点,以节点的nodeName属性为索引。
            item(num):返回位于数字num位置处的节点。
          @attributes属性中包含一系列节点,每个节点nodeName为特性名,nodeValue为特性值。

var id = element.attribute.getNamedItem("id").nodeValue;
var id = element.attribute["id"].nodeValue;

          @removeNamedItem()效果同removeAttribute(),但removeNamedItem()返回被删除特性的Attr节点

          @迭代元素的每个特性:

function outputAttributes(element){
    var pairs = new Array(),
        attrName,
        attrValue,
        i,
        len;

    for (i=0, len=element.attributes.length; i < len; i++){
        attrName = element.attributes[i].nodeName;
        attrValue = element.attributes[i].nodeValue;
        pairs.push(attrName + "=\"" + attrValue + "\"");
    }
    return pairs.join(" ");
}
迭代元素特性

            以上代码并不完善,IE7-会返回HTML元素中的所有可能特性,包括没指定的特性。
            解决方案:每个特性节点都有一个specified属性
              该属性值为true时,表示要么在HTML中指定了相应特性,要么通过setAttribute()方法设置了该特性。
              在IE中没设置的特性的specified属性值为false。
              而在其他浏览器,根本不会为未设置的特性生成对应的特性节点。所有特性节点的specified属性值都为true。

function outputAttributes(element){
    var pairs = new Array(),
        attrName,
        attrValue,
        i,
        len;

    for (i=0, len=element.attributes.length; i < len; i++){
        attrName = element.attributes[i].nodeName;
        attrValue = element.attributes[i].nodeValue;
        if (element.attributes[i].specified){
            pairs.push(attrName + "=\"" + attrValue + "\"");
        }
    }
    return pairs.join(" ");
}
改良

        ⑤ 创建元素

          document.createElement(),一个参数(标签名)。
            @使用createElement()创建新元素时,也为元素设置了ownerDocument属性
            @传入完整的元素标签,能解决IE7-中创建元素的一些问题:
              不能设置动态创建<iframe>元素的name特性;
              不能通过标签元素的reset()方法重设动态创建的<input>元素;
              动态创建的type属性值为reset的<button>元素重设不了表单;
              动态创建的一批name值相同的单选按钮彼此毫无关系。
            @上述IE7-中的问题都能通过给createElement()穿日完整的标签解决:

if(client.browser.ie && client.browser.ie <= 7){
  var iframe = document.createElement("<iframe name=\"maiframe\"></iframe>");
  var input = document.createElement("<input type=\"checkbox\"/>");
  var button = document.createElement("<buttom type=\"reset\"></button>");
  var radio1 = document.createElement("<input type=\"radio\" name=\"choice\" value=\"1\"/>");
  var radio2 = document.createElement("<input type=\"radio\" name=\"choice\" value=\"2\"/>");
}
解决IE7-中创建一些元素的问题

     10.1.4 Text类型

      文本节点由Text类型表示,不支持子节点。
      @可通过nodeValue属性或data属性访问Text节点中包含的文本。
      @操作节点中的文本:
        appendData(text):将text添加到节点的末尾。
        deleteData(offset,count):从offset位置开始删除count个字符。
        insertData(offset,text):从offset位置插入text。
        replaceData(offset,count,text):用text代替从offset位置开始的count个字符。
        splitText(offset):从offset位置将文本分成两部分。
        substringData(offset,count):提取从offset位置到offset+count位置的文本。
        length属性:节点中的字符个数。
      @在修改文本节点时,字符串会经过编码,即不会字符串中的标签会与文本的形式显示:

div.firstChild.nodeValue = "Some <strong>other</strong> message";
//输出Some <strong>other</strong> message

      ① 创建文本节点

        document.createTextNode(),同上,传入的文本参数也会进行编码。
          @连续添加多个文本节点时,各相邻节点会连起来显示,中间无空格。

        function addNode(){
        
            var element = document.createElement("div");
            element.className = "message";
            
            var textNode = document.createTextNode("11111");
            element.appendChild(textNode);
            
            var anotherTextNode = document.createTextNode("22222");
            element.appendChild(anotherTextNode);
            
            document.body.appendChild(element);
        }

//输出1111122222
添加 多个文本节点

      ② 规范化 文本节点

        normalize():能将包含的多个文本节点合并成一个。此方法由Node类型定义,故存在于所有节点类型中。

function addNode(){

    var element = document.createElement("div");
    element.className = "message";
    
    var textNode = document.createTextNode("Hello world!");
    element.appendChild(textNode);
    
    var anotherTextNode = document.createTextNode("Yippee!");
    element.appendChild(anotherTextNode);
    
    document.body.appendChild(element);
    
    alert(element.childNodes.length);  //2
    
    element.normalize();
    alert(element.childNodes.length);  //1
    alert(element.firstChild.nodeValue);  //"Hello World!Yippee!"
    
}
合并 多个文本节点

      ③ 分隔文本节点

        splitText():此方法会将文本节点分成两个文本节点,原来的文本节点剩下没指定的,新文本节点包含指定的文本,并被此方法返回。

    10.1.5 Comment类型

      @注释类型Comment与Text类型继承自相同的基类。
      @浏览器不会识别位于</html>标签后的注释,故应该保证它们是<html>的后代。

    10.1.6 CDATASection类型

      此类型只针对XML文档,表示CDATA区域。

    10.1.7 DocumentType类型

      包含文档的dictype有关的所有信息,仅有Firefox、Safari、Chrome4 和 Opera支持。

    10.1.8 DocumentFragment类型

      @所有节点类型中,只有DocumentFragment类型没有对应的标记。
      @DOM规文档片段是一种“轻量级”文档,可以包含和控制节点,但不会像完整的文档那样占用额外的资源。
      ①document.createDocumentFragment()方法,创建文档片段。
        @继承了Node的所有方法。
        @将文档中的节点添加到文档片段中,就会从文档树中移除节点。添加在文档片段的新节点同样不属于文档树。
        @文档片段本身永远不会成为文档树的一部分。
      ②当需要给一个<ul>元素添加三个列表项时,逐个添加列表项节点会导致浏览器反复渲染和呈现新信息,使用文档片段能避免:

<body>
    <ul id="myList"></ul>
    <input type="button" value="Add Items" onclick="addItems()">

    <script type="text/javascript">
        function addItems(){
        
            var fragment = document.createDocumentFragment();
            var ul = document.getElementById("myList");
            var li = null;
            
            for (var i=0; i < 3; i++){
                li = document.createElement("li");
                li.appendChild(document.createTextNode("Item " + (i+1)));
                fragment.appendChild(li);
            }
            
            ul.appendChild(fragment);    

            
        }

    </script>
</body>
文档片段-应用

        @添加后,文档片段中的子节点会被删除。

    10.1.9 Attr类型

      元素的特性在DOM中与Attr类型表示。
      @特性是存在于元素的attribute属性中的节点,但特性不被认为是DOM文档的一部分。
      @Attr类型有三个属性:name(特性名,同nodeName)、value(特性值,同nodeValue) 和 specified(布尔值,区分特性是指定还是默认)。

        function assignAttribute(){
            var element = document.getElementById("myDiv");
            var attr = document.createAttribute("align");
            attr.value = "left";
            element.setAttributeNode(attr);
            
            alert(element.attributes["align"].value);       //"left"
            alert(element.getAttributeNode("align").value); //"left"
            alert(element.getAttribute("align"));           //"left"
        }
name、value 和 specified

      @实际上,使用getAttribute()等3个方法比操作特性节点更方便。

  10.2 DOM操作技术

    10.2.1 动态脚本

      ① 通过<script>元素,有 src属性指定外部文件 和 本身包围代码 2种方法向页面添加JavaScript代码。
      ② 动态脚本,指在加载页面时不存在,但在某时通过修改DOM动态添加的脚本。
        @创建动态脚本也有两种方法:插入外部文件 和 直接插入JavaScript代码。
      ③ IE中,<script>为一个特殊元素,不允许DOM访问其子节点:
        script.appendChild(document.createTextNode("function sayHi(){alert("Hello!");}")); (在IE会报错)
        @IE中可以使用script的text属性 指定JavaScript代码:

        function loadScriptString(code){
            var script = document.createElement("script");
            script.type = "text/javascript";
            try {
                script.appendChild(document.createTextNode(code));
            } catch (ex){
                script.text = code;
            }
            document.body.appendChild(script);
        }
    
        function addScript(){
            loadScriptString("function sayHi(){alert('hi');}");
            sayHi();
        }
兼容各浏览器

      这样加载的代码会在全局作用域中执行,与在全局作用域中 把相同的字符串传递给你eval()一样。

    10.2.2 动态样式

      ①有2个元素 能将CSS样式包含到HTML页面中,<link>元素包含外部文件,<style>元素指定嵌入的样式。
        @加载外部样式文件是异步的,即与执行JavaScript代码的过程没有固定程序。
      ②同样的,IE中<style>为一个特殊的元素,不允许访问其子节点:
        style.appendChild(document.createTextNode("body{color:red;}")); (在IE会报错)
        @IE中可以使用访问元素的styleSheet属性的cssText属性 指定CSS样式:

        function loadStyleString(css){
            var style = document.createElement("style");
            style.type = "text/css";
            try{
                style.appendChild(document.createTextNode(css));
            } catch (ex){
                style.styleSheet.cssText = css;
            }
            var head = document.getElementsByTagName("head")[0];
            head.appendChild(style);
        }
    
        function addStyle(){
            loadStyleString("body{background-color:red}"); 
        }
兼容各浏览器

        @在针对IE编码时,应注意使用styleSheet.cssText属性:
          在重用同个<style>元素并再次设置这个属性时,可能会导致浏览器崩溃。将cssText属性设为空字符串也可能使浏览器崩溃。

    10.2.3 操作表格

      为了方便构建表格,HTML DOM还为<table>、<tbody> 和 <tr>元素添加了一些属性:
        为<teble>元素添加的属性和方法:
          caption:(若有)保存着对<caption>元素的指针。
          tHead:(若有)同上。
          tFoot:(若有)同上。
          tBodies:一个所有<tbody>元素的HTMLCollection。
          rows:一个所有行的HTMLCollection。
          createCaption:创建该元素,放如表格,返回引用。
          createTHead():同上。
          createTFoot():同上。
          deleteCaption():删除<caption>元素。
          deleteTHead():同上。
          deleteTFoot():同上。
          insertRow(pos):向rows集合中的指定位置 插入一行。
          deleteRow(pos):删除指定位置的一行。
        <tbody>:
          rows:一个保存着<tbody>元素中行的HTMLCollection。
          insertRow(pos):向rows集合中指定位置插入一行,返回新行的引用。
          deleteRow(pos):删除指定位置的行。
        <tr>:
          cells():一个保存着<tr>元素中的单元格的HTMLCollection。
          insertCell(pos):向cells集合中的指定位置插入一个单元格,返回新单元格引用。
          deleteCell(pos):删除指定位置的单元格。

    //创建talbe
    var table = document.createElement('table');
    table.border = 1;
    table.width  = "100%";

    //创建tbody
    var tbody = document.createElement('tbody');
    table.appendChild(tbody);

    //创建第一行
    tbody.insertRow(0);
    tbody.rows[0].insertCell(0);
    tbody.rows[0].cells[0].appendChild(document.createTextNode('cell 1,1'));
    tbody.rows[0].insertCell(1);
    tbody.rows[0].cells[1].appendChild(document.createTextNode('cell 2,1'));

    //创建第二行
    tbody.insertRow(1);
    tbody.rows[1].insertCell(0);
    tbody.rows[1].cells[0].appendChild(document.createTextNode('cell 1,2'));
    tbody.rows[1].insertCell(1);
    tbody.rows[1].cells[1].appendChild(document.createTextNode('cell 2,2'));

    document.body.appendChild(table);
应用

    10.2.4 使用NodeList

      NodeList、NameNodeMap 和 HTMLColletction 三个集合都是动态的。
      @浏览器不会将创建的所有集合保存在一个列表中,而是在下一次访问集合是更新集合。
      迭代一个NodeList时,应该在比较之前,先将其length保存在一个变量中:

var divs = document.getElementByTagName("div"),
i,
len,
div;
for(i=o, len=divs.length; i<len; i++){
     div = document.createElement("div");
     document.body.sppendChild(div);
}
迭代一个NodeList
原文地址:https://www.cnblogs.com/slowsoul/p/3086016.html