• JavaScript学习 七、DOM


     DOM(文档对象模型)是针对HTML和XML文档的一个API。DOM描绘了一个层次化的节点树。允许开发人员添加、移除、修改页面的某一部分。

    节点层次

     文档节点是每个文档的根节点,文档元素是文档的最外层元素,文档中其他说有的元素都包含在文档元素中,每个文档只能有一个文档元素,在HTML 中,文档元素始终是<html> 元素,在XML 中没有预定义的元素,因此任何元素都可能成为文档元素。

    每一段标记都可以通过树中的一个节点来表示:HTML 元素通过元素节点表示,特性(attribute)通过特性节点表示,文档类型通过文档类型节点表示,而注释则通过注释节点表示,总共有12 种节点类型。

     1.Node类型

    DOM1 级定义了一个Node 接口,该接口将由DOM中所有节点类型实现。这个Node在JavaScript中是作为Node 类型实现的;JavaScript 中所有节点都继承自Node 类型,因此所有节点类型都共享相同的基本属性和方法。

    属性

    每个节点都有一个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)

     可以用节点的nodeType属性和上面的常量比较,如果相等,则说明节点是 该类型的元素。由于IE没有公开Node类型的构造函数,所以为了确保跨浏览器兼容,最好还是将nodeType属性与数字值进行比较。

    if(someNode.nodeType == 1){  //Node.ELEMENT_NODE
        alert("Node is an element");
    }

     可以使用nodeName 和 nodeValue 者两个属性来了解节点的具体信息,对于元素节点,nodeName中保存的始终都是元素的表签名,而nodeValue 则始终为null。

    每一个节点都保存者一个childNodes 属性,其中保存着一个NodeList对象。NodeList是一种类似于数组的对象,用于保存一组有序的节点。NodeList 对象的独特之处在于,它实际上是基于DOM结构动态执行查询的结果,因此DOM结构的变化能够自动反应在NodeList 对象中。

    可以使用方括号或者item方法来访问NodeList中的对象。

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

    可以使用Array.prototype.slice()方法将NodeList转换成普通的ArrayList对象。

    var arrayOfNodes = Array.prototype.slice.call(someNode.childNodes, 0);

    每个节点还有 prentNode、previousSibling、nextSibling、firstChild、lastChild等属性。顾名思义,不再一一介绍。

    方法

    节点的关系指针都是只读的,所以DOM提供了一些操作节点的方法。其中最常用的是appendChild(),用于向childNodes 列表的末尾添加一个节点。返回新增的节点。

    使用insertBefore()方法可以把节点方法childNodes 列表中某个特定的位置上。接收两个参数:要插入的节点和作为参照的节点。插入节点后,被插入的节点会变成参照节点的前一个兄弟节点(previousSibling),同时被方法返回。如果参照节点是null, 则insertBefore() 与 appendChild() 执行相同的操作。

     replaceChild()方法接收两个参数:要插入的节点和要替换的节点。要替换的节点将由这个方法返回并从文档树中被移除,同时由要插入的节点占据其位置。

    removeChild()方法接收一个参数,即要移除的节点。被移除的节点将成为方法的返回值。

    cloneNode() 用于创建调用这个方法的节点的一个完全相同的副本。该方法接收一个布尔值参数,表示是否执行深复制。

    2.Document类型

    JavaScript 通过Document 类型表示文档,在浏览器中,document 对象是HTMLDocument的一个实例,表示整个HTML页面。而且document对象是window对象的一个属性,因此可以作为全局对象来访问。

    document 的 nodeType 为9, nodeName 为“#document”,nodeValue 为null parentNode 为null,ownerDocument为null。

    Document 节点的子节点可以是DocumentType、Element、ProcessingInstruction 或 Comment,但还是有两个内置的访问其子节点的快捷方式。

    第一个就是documentElement 属性,该属性始终指向 HTML 页面中的<html> 元素。另一个就是body 属性,直接指向<body> 元素。

    document 对象有一些标准的Document 对象所没有的属性。这些属性提供了document 对象所表现的页面的一些信息。

    第一个属性是 title,包含者<title> 元素中的文本----显示在浏览器窗口的标题栏或标签页上。通过这个属性可以取得当前页面的标题,也可以修改当前页面的标题并反应在浏览器的标题栏中。

    URL属性中包含页面完整的URL,domain 属性中包含页面的域名,而referrer 属性中则保存着联街道当前页面的哪个页面的URL。在没有来源页面的情况下,referrer 属性中可能会包含空字符串。所有这些信息都存在于请求的HTTP 头部,只不过是通过这些属性让我们能够在JavaScript中访问他们而已。

    document提供了两个方法用于查找某个或某组元素的引用:getElementById() 和 getElementsByTagName()。

    getElementsByTagName() 函数返回的是包含0或多个元素的 NodeList。在HTML中,这个方法会返回一个HTMLCollection 对象,作为一个动态集合,该对象与NodeList 非常类似。

    getElementsByName() 方法是HTMLDocument 特有的方法,返回带有给定name 特性的所有元素。

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

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

    3.Element类型

    • nodeType 值为 1
    • nodeName 值为元素表签名
    • nodeValue 值为 null
    • parentNode 可能是 Document或 Element
    • 其子节点可能是 Element、Text、Comment、ProcessingInstruction、CDATASection 或 EntityReference。

    要访问元素的标签名,可以使用nodeName属性,也可以使用tagName 属性;这两个属性会返回相同的值。

    所有的HTML元素都由HTMLElement 类型表示,不是直接通过这个类型也是通过它的子类型来表示。HTMLElement 类型直接继承自Element 并添加了一些属性。添加的这些属性分别对应于每个HTML都存在的下列标准特性:

    • id,元素在文档中的唯一标识符
    • title,有关元素的附加说明信息,一般通过工具提示条显示出来
    • lang,元素内容的语言代码,很少使用
    • dir,语言的方向,值为“ltr”(left-to-right,从左向右)或“rtl”(right-to-left,从右向左),也甚少使用。
    • className,与元素class特性对应,即为元素制定的CSS 类。没有将这个属性命名为class,是因为class 是ECMAScript的保留字。
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title>study</title>
        </head>
        <body>
        <div id="myDiv" class="bd" title="Body text" lang="en" dir="rtl">good morning</div>
            <script type="text/javascript">
            var div = document.getElementById("myDiv");
            alert("id=" + div.id + ", class=" + div.className + ", title=" + div.title + ", lang=" + div.title + ", dir=" + div.dir);  //id=myDiv, class=bd, title=Body text, lang=Body text, dir=rtl
            </script>
        </body>
    </html>

     getAttribute()方法也可以取得属性内容,也可以取得自定义的特性。参数传递属性名称,不去分大小写。

    在通过JavaScript 以编程方式操作DOM 时,开发人员经常不使用getAttribute(),而是只使用对象的属性。只有在取得自定义特性值的情况下,才会使用getAttribute() 方法。

    setAttribute() 方法可以为对象设置属性,也可以操作自定义特性,通过这个方法设置的特性名会被统一转换成小写形式。

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

    Element 类型是使用attributes 属性的唯一一个DOM 节点类型。attributes 属性中包含一个NamedNodeMap,是一个动态集合。元素的每一个特性都是一个Attr节点表示,每个节点都保存在NamedNodeMap对象中。NamedNodeMap对象拥有下列方法:

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

    attributes属性中包含一系列节点,每个节点的nodeName 就是特性的名称,而节点的 nodeValue 就是特性的值。要取得元素的id特性,可以使用以下代码。

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

     一般来说,因为attributes 的方法不够方便,因此开发人员更多的会使用 getAttribute()、setAttributes()、removeAttributes()方法。

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

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

     4.Text类型

    • nodeType 值为3;
    • nodeName 值为 “#text”;
    • nodeValue 值为节点所包含的文本;
    • parentNode是一个Element;
    • 不支持(没有)子节点。

    可以通过nodeValue 属性或者 data 属性来访问Text 节点中包含的文本,这两个属性中包含的值相同。对nodeValue的修改也会通过data反映出来,反之亦然。

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

    • 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 为止处的字符串。

    文本节点还有一个length 属性,保存着节点中字符的数目。

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

    DOM操作技术

     操作表格

    <table> 元素是 HTML中最复杂的结构之一,要想创建表格,一般都必须设计表示表格行、单元格、表头等方面的标签。由于涉及的标签多,因此使用核心的DOM方法创建和修改表格往往都免不了要编写大量的代码。为了方便构建表格,HTML DOM 还为<table>、<tbody>和<tr>元素添加了一些属性和方法。

    为<table>元素添加的属性和方法:

    • caption:保存着对<caption>元素的指针;
    • tBodies:是一个<tbody> 元素的HTMLCollection。
    • tFoot:保存着对 <tfoot>元素的指针;
    • tHead:保存着对<thead>元素的指针;
    • rows:是一个表格中所有行的HTMLCollection;
    • createTHead():创建<thead> 元素,将其放到表格中,返回引用;
    • createTFoot():创建<tfoot> 元素,将其放到表格中,返回引用。
    • createCaption():创建<caption> 元素,将其放到表格中,返回引用。
    • deleteTHead():删除<thead>元素。
    • deleteTFoot():删除<tfoot>元素。
    • deleteCaption():删除<caption> 元素。
    • deleteRow(pos):删除指定位置的行。
    • insertRow(pos):向rows集合中的制定位置插入一行。

    为<tbody> 元素添加的属性和方法:

    • rows:保存着<tbody>元素中的行的HTMLCollection。
    • deleteRow(pos):删除指定位置的行。
    • insertRow(pos):向rows集合中的制定位置插入一行,返回对新插入行的引用。

    为<tr>元素添加的属性和方法:

    • cells:保存着<tr>元素中单元格的HTMLCollection。
    • deleteCell(pos):删除制定位置的单元格。
    • insertCell(pos):向cells集合中的指定位置插入一个单元格返回对新单元格的引用。
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title>study</title>
        </head>
        <body>
        
            <script type="text/javascript">
            var table = document.createElement("table");
            table.border = 1;
            table.width = "100%";
    
            //create tbody
            var tbody = document.createElement("tbody");
            table.appendChild(tbody);
    
            //first row
            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 1, 2"));
    
            //second row
            tbody.insertRow(1);
            tbody.rows[1].insertCell(0);
            tbody.rows[1].cells[0].appendChild(document.createTextNode("Cell 2, 1"));
            tbody.rows[1].insertCell(1);
            tbody.rows[1].cells[1].appendChild(document.createTextNode("Cell 2, 2"));
    
            document.body.appendChild(table);
            
            </script>
        </body>
    </html>

    NodeList

    NodeList、NamedNodeMap 和 HTMLCollection 三个集合都是动态的集合,每当文档结构发生变化是,他们都会更新。因此他们始终都会保存着最新、最准确的信息。从本质上说,所有NodeList对象都是在访问DOM文档时实时运行查询。

    var divs = document.getElementsByTegName("div"), i, div;
    
    for(i = 0; i < divs.length; i++){
        div = document.createElement("div");
        document.body.appendChild(div);
    }

    由于divs是动态集合,所以上面代码会导致无限循环,解决方法是把divs.length保存到另一个变量中进行缓存。

    一般来说,应该尽量减少访问NodeList的次数。

    小结

    DOM是语言中立的 API,用于访问HTML 和XML 文档。DOM1级将HTML和XML 文档形象地看做一个层次化的节点树,可以使用JavaScript来操作这个节点树,进而改变底层文档的外观和结构。

    • 最基本的节点类型是Node, 用于抽象地表示文档中一个独立的部分;所有其他类型都继承自Node。
    • Document 类型表示整个文档,是一组分层节点的根节点,在JavaScript 中, document对象是Document的一个实例。使用document 对象,有很多中方式可以查询和取得节点。
    • Element 节点表示文档中所有HTML 或 XML 元素,可以用来操作这些元素的内容和特性。
    • 另外还有一些节点类型,分别表示文本内容、注释、文档类型、CDATA区域和文档片段。
  • 相关阅读:
    二维码生成库phpqrcode使用小结
    微信扫码支付开发小结
    Xcode下开发c静态库for ios CPU架构 静态库合并
    Android.mk的用法和基础
    Android.mk介绍
    查看与修改网关,DNS
    WebRTC编译系统之GYP,gn和ninja
    sed awk文本处理教程
    有哪些自媒体平台?
    camke使用例程
  • 原文地址:https://www.cnblogs.com/liangflying521/p/5142756.html
Copyright © 2020-2023  润新知