JavaScript的DOM

目录

一、DOM简介

二、节点层次

三、Node类型

3.1、nodeType属性

3.2、nodeName和nodeValue属性

3.3、节点关系

3.4、操作节点

四、Document类型

4.1、文档的子节点

4.2、文档信息

4.3、查找元素

4.4、特殊集合

4.5、DOM一致性检测

4.6、文档写入

五、Element类型

5.1、HTML元素

5.2、操作特性

5.3、attributes属性

5.4、创建元素

5.5、元素的子节点

六、Text类型

6.1、创建文本节点

6.2、规范化文本节点

6.3、分割文本节点

七、Comment类型

八、CDATASection类型

九、DocumentType类型

十、DocumentFragment类型

十一、Attr类型


一、DOM简介

    DOM(文档对象模型)是针对HTMLXML文档的一个API。

    DOM描绘了一个层次化的节点树,允许开发人员添加、移除和修改页面的某一部分。

    W3C的DOM1级规范为基本的文档结构及查询提供了接口,DOM1级的目标主要是映射文档的结构。

二、节点层次

    DOM可以将任何HTML或XML文档描绘成一个由多层节点构成的结构。

    节点分为几种不同的类型,每种类型分别表示文档中不同的信息或标记。

    每个节点都拥有各自的特点、数据和方法,另外也与其他节点存在某种关系。

    文档节点是每个文档的根节点。

    文档节点只有一个子节点,即<html>元素,称之为文档元素,文档元素是文档的最外层元素。

    HTML中共有12种节点类型,这些类型都继承自一个基类型(Node类型

三、Node类型

    DOM1级定义了一个Node接口,这个Node接口在JavaScript中是作为Node类型实现的。

    除了IE8及之前版本的浏览器,在其他所有浏览器中都可以访问到这个类型。

    JavaScript中的所有节点类型都继承自Node类型,因此所有节点类型都共享着相同的基本属性和方法。

3.1、nodeType属性

    每个节点都有一个nodeType属性,用于表明节点类型。

    节点类型由在Node类型中定义的下列12数值常量来表示,任何节点类型必居其一:

  • 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)

    示例

        var someNode = document.getElementById("myTextbox");

        if(someNode.nodeType == Node.ELEMENT_NODE){         // 在IE8及之前版本的浏览器无效
            alert("Node is an element.");
        }

    由于IE8及之前版本的浏览器没有公开Node类型的构造函数,因此上面的代码在IE8及之前版本的浏览器中会导致错误

    为了确保跨浏览器兼容,最好还是将nodeType属性与数字值进行比较:

        var someNode = document.getElementById("myTextbox");

        if(someNode.nodeType == 1){         // 适用于所有浏览器
            alert("Node is an element.");
        }

3.2、nodeName和nodeValue属性

    要了解节点的具体信息,可以使用nodeNamenodeValue这两个属性。

    这两个属性的值完全取决于节点的类型。 

    示例

        if(someNode.nodeType == 1){
            value = someNode.nodeName;  //nodeName的值是元素的标签名
        }

    对于元素节点,nodeName中保存的始终都是元素的标签名,而nodeValue的值则始终为null

3.3、节点关系

    ①childNodes属性

    每个节点都有一个childNodes属性,其中保存着一个NodeList对象。

    NodeList是一种类数组对象,用于保存一组有序的节点,可以通过位置来访问这些节点。

    虽然可以通过方括号语法来访问NodeList的值,而且这个对象也有length属性,但它并不是Array的实例

    NodeList对象实际上是基于DOM结构动态执行查询的结果,因此DOM结构的变化能够自动反映在NodeList对象中。

    NodeList是有生命、有呼吸的对象,而不是我们第一次访问它们的某个瞬间拍摄下来的一张快照。

    也可以使用item()方法访问保存在NodeList中的节点:

        var someNode = document.getElementById("myForm");

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

    ②parent、nextSibling、previousSibling、firstChild和lastChild属性

    每个节点都有一个parentNode属性,该属性指向文档树中的父节点。

    另外,通过使用childNodes列表中的每个节点的previousSiblingnextSibling属性,可以访问同一列表中的其他节点。

    列表中第一个节点的previousSibling属性的值和列表中最后一个节点的nextSibling属性的值同样也为null

    父节点的firstChildlastChild属性分别指向其childNodes列表中的第一个和最后一个节点。

    ③hasChildNodes()方法

    hasChildNodes()方法在节点包含一或多个子节点的情况下返回true

    这是比查询childNodes列表的length属性更简单的方法。

    ④ownerDocument属性

    所有节点都有ownerDocument属性,该属性指向表示整个文档的文档节点。

    通过这个属性,我们可以不必在节点层次中通过层层回溯到达顶端,而是可以直接访问文档节点。

3.4、操作节点

    DOM提供了一些操作节点的方法:

  • appendChild()    ——    用于向childNodes列表的末尾添加一个节点,并返回添加的节点
  • insertBefore()    ——    这个方法接受两个参数:要插入的节点和作为参照的节点,插入节点后,被插入的节点会变成参照节点的前一个同胞节点,同时被方法返回。
  • replaceChild()    ——    这个方法接受两个参数:要插入的节点和要替换的节点。要替换的节点将由这个方法返回并从文档树中被移除,同时由要插入的节点占据其位置。
  • removeChild()    ——    这个方法接受一个参数,即要移除的节点。被移除的节点将成为方法的返回值。
  • cloneNode()    ——    用于创建调用这个方法的节点的一个完全相同的副本。cloneNode()方法接受一个布尔值参数,表示是否执行深复制。在参数为true的情况下,执行深复制,也就是复制节点及其整个子节点树;在参数为false的情况下,执行浅复制,即只复制节点本身。
        // 为someNode节点插入一个子节点
        var returnedNode = someNode.appendChild(newNode);
        
        // 在someNode的子节点newNode后面插入一个节点
        var returnedNode2 = someNode.insertBefore(newNode, newNode2);

        // 使someNode的子节点newNode替换为newNode3
        var returnedNode3 = someNode.replaceChild(newNode, newNode3);

        // 移除someNode的最后一个子节点
        var returnedNode4 = someNode.removeChild(someNode.lastChild);
        
        // 深复制,同时复制了someNode的子节点
        var deepNode = someNode.cloneNode(true);   
    
        // 浅复制,只复制someNode节点,不复制它的子节点
        var shallowNode = someNode.cloneNode(false);

四、Document类型

    JavaScript通过Document类型表示文档。

    在浏览器中,document对象是HTMLDocument(继承自Document类型)的一个实例,表示整个HTML页面。

    而且,document对象是window对象的一个属性,可以将其作为全局对象来访问。

    Document节点具有下列特征:

  • nodeType的值为9
  • nodeName的值为"#document"
  • nodeValue的值为null
  • parentNode的值为null
  • ownerDocument的值为null
  • 其子节点可能是一个DocumentType(最多一个)、Element(最多一个)、ProcessingInstruction或Comment

4.1、文档的子节点

    Document节点有两个内置的访问其子节点的快捷方式:

  • documentElement属性    ——    指向HTML页面中的<html>元素,即文档元素
  • 通过childNodes列表访问文档元素

    示例

    html

<html>
    <body>
        
    </body>
</html>

    js

        var html = document.documentElement;        // 取得对<html>的引用
        console.log(html === document.childNodes[0]);   // true
        console.log(html === document.firstChild);      // true

    ①document.body属性

    作为HTMLDocument的实例,document对象还有一个body属性,直接指向<body>元素

    示例

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

    ②document.doctype属性

    Document另一个可能的子节点是DocumentType

    通常将<!DOCTYPE>标签看成一个与文档其他部分不同的实体。

    可以通过document.doctype属性来访问它的信息。

    示例

        var doctype = document.doctype;     // 取得对<!DOCTYPE>的引用

4.2、文档信息

    ①document.title属性

    document.title属性包含着<title>元素中的文本——显示在浏览器窗口的标题栏或标签页上。

    修改title属性的值也会改变<title>元素。

    示例

        // 取得文档标题
        var originalTitle = document.title;

        // 设置文档标题
        document.title = "New page title";

    ②与网页请求有关的属性

    以下三个属性都与对网页的请求有关:

  • URL    ——    包含页面完整的URL(即地址栏中显示的URL)
  • domain    ——    只包含页面的域名
  • referrer    ——    保存着链接到当前页面的那个页面的URL

    URLdomain属性是相互关联的。

    例如,如果document.URL等于http://www.wrox.com/WileyCDA/ ,那么document.domain就等于www.wrox.com

    在这3个属性中,只有domain是可以设置的。但由于安全方面的限制,也并非可以给domain设置任何值。

    如果URL中包含一个子域名,例如p2p.wrox.com,那么就只能将domain设置为父域名"wrox.com",不能将这个属性设置为URL中不包含的域。

    示例

        // 假设页面来自p2p.wrox.com域
        
        document.domain = "wrox.com";       // 设置为父域,成功!

        document.domain = "nczonline.net";  // 设置为URL中不包含的域,失败!

    当页面中包含来自其他子域的框架或内嵌框架时,能够设置document.domain就非常方便了。

    由于跨域安全限制,来自不同子域的页面无法通过JavaScript通信。

    而通过将每个页面的document.domain设置为相同的父域名的值,这些页面就可以互相访问对方包含的JavaScript对象了

    例如,假设有一个页面加载自www.wrox.com,其中包含一个内嵌框架,框架内的页面加载自p2p.wrox.com

    由于document.domain字符不一样,内外两个页面之间无法相互访问对方的JavaScript对象。

    但如果将这两个页面的document.domain值都设置为"wrox.com",它们之间就可以通信了。

    另外,浏览器对domain属性还有一个限制,即如果域名一开始是“松散的”,那么不能将它再设置为“紧绷的”

    示例

        // 假设页面来自于p2p.wrox.com域

        document.domain = "wrox.com";       // 松散的

        document.domain = "p2p.wrox.com";   // 紧绷的(出错!)

4.3、查找元素

    Document类型提供了几个查找元素的方法。

  • document.getElementByID()    ——    取得单个元素的引用
  • document.getElementsByTagName()    ——    接受一个参数,即要取得元素的标签名。返回的是包含零或多个元素的HTMLCollection对象,作为一个“动态”集合,该对象与NodeList非常类似。可以使用方括号语法或item()方法来访问HTMLCollection对象中的项。另外还可以使用nameItem()方法,使用这个方法可以通过元素的name特性取得集合中的项。
  • document.getElementsByName()    ——    返回带有特定name特性的所有元素组成的一个NodeList。

    示例

        var div = document.getElementById("mydiv");

        var images = document.getElementsByTagName("img");
        alert(images.length);                   // 输出图像的数量
        alert(iamges[0].src);                   // 输出第一个图像的src特性
        alert(images.item(0).src);              // 输出第一个图像的src特性
        alert(images.namedItem("myImage"));     // 输出name特性为"myImage"的图像元素

        var radios = document.getElementsByName("color");  

4.4、特殊集合

    document对象还有一些特殊的集合。这些集合都是HTMLCollection对象,为访问文档常用的部分提供了快捷方式,包括:

  • document.anchors    ——    包含文档中所有带name特性的<a>元素
  • document.forms    ——    包含文档中所有的<form>元素,与document.getElementsByTagName("form")得到的结果相同
  • document.images    ——    包含文档中所有的<img>元素,与document.getElementsByTagName('img')得到的结果相同
  • document.links    ——    包含文档中所有带href特性的<a>元素

4.5、DOM一致性检测

    由于DOM分为多个级别,也包含多个部分,因此检测浏览器实现了DOM的哪些部分就十分必要了。

    document.implementation属性就是为此提供相应信息和功能的对象,与浏览器对DOM的实现直接对应。

    DOM1级只为document.implementation规定了一个方法,即hasFeature()

    这个方法接受两个参数:

  • 要检测的DOM功能的名称
  • 版本号

    如果浏览器支持给定名称和版本的功能,则该方法返回true

    示例

        var hasXmlDom = document.implementation.hasFeature("XML", "1.0");

    下表列出了可以检测的不同的值及版本号。

4.6、文档写入

    document对象具有将输出流写入到网页中的能力,这个能力体现在下列4个方法中:

  • write()    ——    接受一个字符串参数,即要写入到输出流中的文本。
  • writeln()    ——    接受一个字符串参数,即要写入到输出流中的文本。会在字符串的末尾添加一个换行符(\n)
  • open()    ——    打开网页的输出流,可以用于打开一个新的浏览器窗口
  • close()    ——    关闭网页的输出流,可以用于关闭浏览器窗口

    可以使用write()writeln()这两个方法向页面中动态地加入内容。

    示例

    <script> 
        document.write("<strong>" + (new Date()).toString() + "</strong>");      
    </script>

    这个例子会创建一个DOM元素,用于输出当前日期和时间,而且可以在将来访问该元素。

    此外,还可以使用write()writeln()方法动态地包含外部资源,例如JavaScript文件等。

    示例

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

    注意:不能直接包含字符串"</script>",因为这会导致该字符串被解释为脚本块的结束,它后面的代码将无法执行。

    另外,如果在文档加载结束后再调用document.write(),那么输出的内容将会重写整个页面。

    示例

    <script> 
        window.onload = function(){
            document.write("Hello world!");
        };
    </script>

五、Element类型

    Element类型用于表现XML或HTML元素,提供了对元素标签名、子节点及特性的访问。

    Element节点具有以下特征:

  • nodeType的值为1
  • nodeName的值为元素的标签名,等同于tagName属性
  • nodeValue的值为null
  • parentNode可能是Document或Element
  • 其子节点可能是Element、Text、Comment、ProcessingInstruction、CDATASection或EntityReference

5.1、HTML元素

    所有HTML元素都由HTMLElement类型表示,不是直接通过这个类型,也是通过它的子类型来表示。

    HTMLElement类型继承自Element并添加了一些属性。

    添加的这些属性分别对应于每个HTML元素都存在的下列标准特性:

  • id    ——    元素在文档中的唯一标识符
  • title    ——    有关元素的附加说明信息,一般通过工具提示条显示出来
  • lang    ——     元素内容的语言代码,很少使用
  • dir    ——    语言的方向,值为'ltr‘(left-to-right,从左至右)或"rtl"(right-to-left,从右向左),也很少使用。
  • className    ——    与元素的class特性对应

    示例

    <div id="myDiv" class="abc" title="Body text" lang="en" dir="ltr"></div>

    <script> 
        var div = document.getElementById("myDiv");
        console.log(div.id);        // "myDiv"
        console.log(div.className); // "abc"
        console.log(div.title);     // "Body text"
        console.log(div.lang);      // "en"
        console.log(div.dir);       // "ltr"
    </script>

    也可以修改对应的每个特性:

        div.id = "someOtherId";
        div.className = "ft";
        div.title = "Some other text";
        div.lang = "fr";
        div.dir = "rtl";

    下表列出了所有HTML元素以及与之关联的类型:

5.2、操作特性

    操作元素特性的方法主要有三个:

  • getAttribute()    ——    取得元素特性
  • setAttribute()    ——    设置元素特性
  • removeAttribute()    ——    删除元素特性

    传递给getAttribute()的特性名与实际的特性名相同,因此要想得到class特性值,应该传入"class"而不是"className"。

    特性的名称是不区分大小写的,即“ID”和"id"代表的都是同一个特性。

    示例

var value = div.getAttribute("my_special_attribute"); // 取得自定义特性值

   任何元素的所有特性,都可以通过DOM元素本身的属性来访问。

    但是,只有公认的(非自定义的)特性才会以属性的形式添加到DOM对象中

    示例

    html

    <div id="myDiv" align="left" my_special_attribute="hello!"></div>

    Js

        var div = document.getElementById("myDiv");
        console.log(div.id);                      // "myDiv"
        console.log(div.my_special_attribute);    // undefined
        console.log(div.align);                   // "left"

    有两类特殊的特性,它们虽然有对应的属性名,但属性的值与通过getAttribute()返回的值并不相同。

    第一类特性就是style

  • 通过getAttribute()返回时,返回的style特性值中包含的是CSS文本
  • 通过属性来访问它则会返回一个对象

    第二类特性就是onclick这样的事件处理程序:

  • 如果通过getAttribute()访问,返回相应代码的字符串
  • 通过onclick属性访问,则会返回一个JavaScript函数

    设置特性对应的方法是setAttribute()

    如果特性不存在,setAttribute()则创建该属性并设置相应的值。

    示例

        div.setAttribute("id", "someOtherId");

    注意:像下面这样为DOM元素添加一个自定义的属性,该属性不会自动成为元素的特性。

        div.mycolor = "red";
        console.log(div.getAttribute("mycolor"));     // null

    removeAttribute()方法用于彻底删除元素的特性。

    调用这个方法不仅会清除特性的值,而且也会从元素中完全删除特性。

    示例

        div.removeAttribute("class");

5.3、attributes属性

    Element类型中的attributes属性中包含一个NamedNodeMap,与NodeList类似,也是一个“动态”的集合。

    元素的每一个特性都由一个Attr节点表示,每个节点都保存在NamedNodeMap对象中。

    NamedNodeMap对象拥有下列方法:

  • getNamedItem(name)    ——    返回nodeName属性等于name的节点
  • removeNamedItem(name)    ——    从列表中移除nodeName属性等于name的节点
  • setNamedItem(node)    ——    向列表中添加节点,以节点的nodeName属性为索引
  • item(pos)    ——    返回位于数字pos位置处的节点

    attributes属性中包含一系列节点,每个节点的nodeName就是特性的名称,而节点的nodeValue就是特性的值。

    要取得元素的id特性,可以使用以下代码:

        var id = div.attributes.getNamedItem("id").nodeValue;

    也可以使用方括号语法通过特性名称访问节点:

        var id = div.attributes["id"].nodeValue;

    可以使用这种语法来设置特性的值:

        div.attributes["id"].nodeValue = "someOtherId";

    调用removeNamedItem()方法与在元素上调用removeAttribute()方法的效果相同——直接删除具有给定名称的特性。

    但removeNamedItem()返回表示被删除特性的Attr节点:

        var oldAttr = element.attributes.removeNamedItem("id");

    setNamedItem()是一个很不常用的方法,通过这个方法可以为元素添加一个新特性,为此需要为它传入一个特性节点:

        element.attributes.setNamedItem(newAttr);

    由于前面介绍的attributes的方法不够方便,因此开发人员更多的会使用getAttribute()removeAttribute()setAttribute()方法。

    不过,如果想要遍历元素的特性,attributes属性倒是比较适合。

    示例

        function outputAttributes(element){
            var pairs = new Array(),
                attrName,
                attrValue;
            
            for(var 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(" ");
        }

5.4、创建元素

    使用document.createElement()方法可以创建新元素,这个方法只接受一个参数,即要创建元素的标签名。

    示例

        var div = document.createElement("div");
        div.id = "myNewDiv";
        div.className = "box";
        
        document.body.appendChild(div);

5.5、元素的子节点

    元素的childNodes属性中包含了它的所有子节点,这些子节点有可能是元素、文本节点、注释或处理命令。

    不同的浏览器在看待这些节点方面存在显著的不同。

    示例

    <ul id="myList">
        <li>Item 1</li>
        <li>Item 2</li>
        <li>Item 3</li>
    </ul>

    如果是IE来解析这些代码,那么<ul>元素会有3个子节点,分别是3个<li>元素。

    但如果是在其他浏览器中,<ul>元素都会有7个元素,包括3个<li>元素和4个文本节点(表示<li>元素之间的空白符)。

    因此,如果需要通过childNodes属性遍历子节点,那么一定要在执行某项操作前,先检查一下nodeType属性。

    示例

        for(var i = 0, len = element.childNodes.length; i < len; i++){
            if(element.childNodes[i].nodeType == 1){        // 如果是元素节点
                // 执行某些操作
            }
        }

    另外,元素也支持getElementsByTagName()方法,以取得当前元素的所有子节点。

    示例

        var ul = document.getElementById("myList");
        var items = ul.getElementsByTagName("li");

六、Text类型

    文本节点由Text类型表示,包含的是可以照字面解释的纯文本内容。

    纯文本中可以包含转义后的HTML字符,但不能包含HTML代码。

    Text节点具有以下特征:

  • nodeType的值为3
  • nodeName的值为“#text”
  • nodeValue或data的值为节点所包含的文本
  • parentNode是一个Element
  • length保存着节点中字符的数目

    使用下列方法可以操作节点中的文本:

  • appendData(text)    ——    将text添加到节点的末尾
  • deleteData(offset, count)    ——    从offset指定的位置开始删除count个字符
  • insertData(offset, text)    ——    在offset指定的位置插入text
  • replaceData(offset, count, text)    ——    用text替换从offset指定的位置开始到offset + count为止处的文本
  • splitText(offset)    ——    从offset指定的位置将当前文本节点分成两个文本节点
  • substringData(offset, count)    ——    提取从offset指定的位置开始到offset + count为止处的字符串

    在取得文本节点的引用后,就可以像下面这样来修改它:

        div.firstChild.nodeValue = "Some other message";

6.1、创建文本节点

    可以使用document.createTextNode()创建新文本节点,这个方法接受一个参数——要插入节点中的文本。

    示例

        var element = document.createElement('div');

        var textNode = document.createTextNode("Hello World!");
        element.appendChild(textNode);

        document.body.appendChild(element);

    一般情况下,每个元素只有一个文本子节点。不过在某些情况下也可能包含多个文本子节点。

    示例

        var element = document.createElement('div');

        var textNode = document.createTextNode("Hello World!");
        element.appendChild(textNode);

        var anotherTextNode = document.createTextNode("Yippee!");
        element.appendChild(anotherTextNode);

        document.body.appendChild(element);

    如果两个文本节点是相邻的同胞节点,那么这两个节点中的文本就会连起来显示,中间不会有空格。

6.2、规范化文本节点

    DOM文档中存在相邻的同胞文本节点很容易导致混乱,因为分不清哪个文本节点表示哪个字符串。

    于是就催生了一个能将相邻文本节点合并的方法normalize(),这个方法是由Node类型定义的(因而在所有节点类型中都存在)。

    如果在一个包含两个或多个文本节点的父元素上调用normalize()方法,则会将所有文本节点合并成一个节点。

    结果节点的nodeValue等于将合并前每个文本节点的nodeValue值拼接起来的值。

    示例

        var element = document.createElement('div');

        var textNode = document.createTextNode("Hello World!");
        element.appendChild(textNode);

        var anotherTextNode = document.createTextNode("Yippee!");
        element.appendChild(anotherTextNode);

        document.body.appendChild(element);

        console.log(element.childNodes.length);     // 2

        element.normalize();    
        console.log(element.childNodes.length);     // 1
        console.log(element.firstChild.nodeValue);  // "Hello world!Yippee!"

6.3、分割文本节点

    Text类型提供了一个作用与normalize()相反的方法:splitText()

    这个方法会将一个文本节点分成两个文本节点,即按照指定的位置分割nodeValue值。

    原来的文本节点将包含从开始到指定位置之前的内容,新文本节点将包含剩下的文本。

    这个方法会返回一个新文本节点,该节点与原节点的parentNode相同。

        var element = document.createElement('div');

        var textNode = document.createTextNode("Hello World!");
        element.appendChild(textNode);

        document.body.appendChild(element);

        var newNode = element.firstChild.splitText(5);
        console.log(element.firstChild.nodeValue);      // "Hello"
        console.log(newNode.nodeValue);                 // " world!"
        console.log(element.childNodes.length);         // 2

七、Comment类型

    注释在DOM中是通过Comment类型来表示的。

    Comment节点具有下列特征:

  • nodeType的值为8
  • nodeName的值为"#comment"
  • nodeValue或data的值是注释的内容
  • parentNode可能是Document或Element
  • 不支持(没有)子节点

    Comment类型与Text类型继承自相同的基类,因此它拥有除splitText()之外的所有字符串操作方法。

    注释节点可以通过其父节点来访问。

    示例

    html

    <div id="myDiv"><!-- A Comment --></div>

    JS

        var div = document.getElementById("myDiv");
        var comment = div.firstChild;
        console.log(comment.data);          // "A comment"

    另外,使用document.createComment()并为其传递注释文本也可以创建注释节点  

    示例

        var comment = document.createComment("A comment ");

    开发人员很少会创建和访问注释节点,因为注释节点对算法鲜有影响。

    此外,浏览器也不会识别位于</html>标签后面的注释。

八、CDATASection类型

九、DocumentType类型

    DocumentType包含着与文档的doctype有关的所有信息,它具有下列特征:

  • nodeType的值为10
  • nodeName的值为doctype的名称
  • nodeValue的值为null
  • parentNode是Document
  • 不支持(没有)子节点

    在DOM1级中,DocumentType对象不能动态创建,而只能通过解析文档代码的方式来创建。

    支持它的浏览器会把DocumentType对象保存在document.doctype中。

    DOM1级描述了DocumentType对象的3个属性:

  • name    ——    表示文档类型的名称
  • entities    ——    由文档类型描述的实体的NamedNodeMap对象
  • notations    ——    由文档类型描述的符号的NamedNodeMap对象。

    浏览器中的文档使用的都是HTML或XHTML文档类型,因而entitiesnotations都是空列表(列表中的项来自行内文档类型声明)。

    只有name属性是有用的,这个属性中保存的是文档类型的名称,也就是出现在<!DOCTYPE之后的文本。

    以下面严格型HTML 4.01的文档类型声明为例:

    DocumentTypename属性中保存的就是"HTML":

        alert(document.doctype.name);    // "HTML"

十、DocumentFragment类型

    在所有节点类型中,只有DocumentFragment在文档中没有对应的标记。

    DOM规定文档片段是一种”轻量级“的文档,可以包含和控制节点,但不会像完整的文档那样占用额外的资源

    DocumentFragment节点具有下列特征:

  • nodeType的值为11
  • nodeName的值为"#document-fragment"
  • nodeValue的值为null
  • parentNode的值为null
  • 子节点可以是Element、ProcessingInstruction、Comment、Text、CDATASection或EntityReference

    虽然不能把文档片段直接添加到文档中,但可以将它作为一个”仓库“来使用,即可以在里面保存将来可能会添加到文档中的节点。

    要创建文档片段,可以使用document.createDocumentFragment()方法。

    示例

        var fragment = document.createDocumentFragment();

    文档片段继承了Node的所有方法,通常用于执行那些针对文档的DOM操作。

    如果将文档中的节点添加到文档片段中,就会从文档树中移除该节点,也不会从浏览器中再看到该节点。

    添加到文档片段中的新节点同样也不属于文档树。

    可以通过appendChild()insertBefore()将文档片段中内容添加到文档中。

    在将文档片段作为参数传递给这两个方法时,实际上只会将文档片段的所有子节点添加到相应位置上,文档片段本身永远不会成为文档树的一部分

    示例

    html

    <ul id="myList"></ul>

    想为这个<ul>元素添加3个列表项,如果逐个地添加列表项,将会导致浏览器反复渲染(呈现)新信息。

    为避免这个问题,可以像下面这样使用一个文档片段来保存创建的列表项,然后再一次性将它们添加到文档中:

        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);

十一、Attr类型

    元素的特性在DOM中以Attr类型来表示。

    从技术角度讲,特性就是存在于元素的attributes属性中的节点。

    特性节点具有下列特征:

  • nodeType的值为2
  • nodeName的值是特性的名称
  • nodeValue的值是特性的值
  • parentNode的值为null
  • 在HTML中不支持(没有)子节点
  • 在XML中子节点可以是Text或EntityReference

    Attr对象有3个属性:

  • name    ——    特性名称(与nodeName的值相同)
  • value    ——    特性的值(与nodeValue的值相同)
  • specified    ——    布尔值,用以区别特性是在代码中指定的,还是默认的。

    使用document.createAttribute()并传入特性的名称可以创建新的特性节点。

    示例

    要为元素添加align特性,可以使用下列代码:

        var attr = document.createAttribute("align");
        attr.value = "left";
        element.setAttributeNode(attr);
        console.log(element.attributes['align'].value);         // "left"
        console.log(element.getAttributeNode('align').value)    // "left"
        console.log(element.getAttribute('align'));             // "left"

    getAttributeNode()方法用于获取元素的特性节点。

    setAttributeNode()方法用于设置元素的特性节点。

    

猜你喜欢

转载自blog.csdn.net/qq_35732147/article/details/83030245
今日推荐