DOM总结(1.节点类型)

186 阅读9分钟

1.所有节点都有的属性和方法

1.1 nodeName与nodeValue

nodeName与nodeValue保存着与结点有关的信息。这两个属性的值完全取决于节点类型。

1.2 节点关系

childNodes

每个节点都有一个childNodes属性,其中包含一个NodeList的实例。NodeList是一个类数组对象,用于存储可以按位置存取的有序节点。NodeList中的元素可以使用中括号或使用item()方法访问。

let firstChild = someNode.childNodes[0]; 
let secondChild = someNode.childNodes.item(1); 

注:NodeList是实时的活动对象,而不是第一次访问时所获得内容的快照。

parentNode previousSibling nextSibling

parentNode:指向父节点

previousSibling:指向前一个同胞节点

nextSibling:指向下一个同胞节点

1.3 操纵节点

appendChild()

用于在childNodes列表末尾添加节点,返回新添加的节点。 如果把文档中已经存在的节点传给appendChild(),则这个节点会从之前的位置被转移到新位置(一个节点也不会在文档中同时出现在两个或更多个地方)。

insertBefore()

特定位置插入节点,这个方法接收两个参数:要插入的节点和参照节点。调用这个方法后,要插入的节点会变成参照节点的前一个同胞节点,并被返回。如果参照节点是null,则insertBefore()与appendChild()效果相同

replaceChild()

替换节点,该方法接收两个参数:要插入的节点和要替换的节点

removeChild()

移除节点,这个方法接收一个参数,即要移除的节点。被移除的节点会被返回。

1.4 其他方法

cloneNode()

克隆节点,该方法接收一个布尔值参数,表示是否深复制。在传入true参数时,会进行深复制,即复制节点及其整个子DOM树。如果传入false,则只会复制调用该方法的节点。复制返回的节点属于文档所有,但尚未指定父节点,所以可称为孤儿节点(orphan)。

注:cloneNode()方法不会复制添加到DOM节点的JavaScript属性,比如事件处理程序。这个方法只复制HTML属性,以及可选地复制子节点。除此之外则一概不会复制。

2.Document类型

Document类型是JavaScript中表示文档节点的类型。在浏览器中,文档对象document是HTMLDocument的实例(HTMLDocument继承Document),表示整个HTML页面。document是window对象的属性。

Document类型可以表示HTML页面或其他XML文档,但最常用的还是通过HTMLDocument的实例取得document对象。document对象可用于获取关于页面的信息以及操纵其外观和底层结构。

2.1 文档(document)子节点

通过下面这些属性可以快捷的访问文档的子节点

documentElement

该属性始终指向<html>元素

body

指向<body>元素

doctype

指向<!doctype>

2.2 文档信息

title

通过这个属性可以读写页面的标题,修改后的标题也会反映在浏览器标题栏上。不过,修改title属性并不会改变<title>元素。

URL、domain、referer

URL包含当前页面的完整URL(地址栏中的URL)。

domain包含页面的域名。

referrer包含链接到当前页面的那个页面的URL。如果当前页面没有来源,则referrer属性包含空字符串。

2.3 定位元素

getElementById()、getElementsByTagName()、getElementsByName()

getElementById():接收一个要获取元素的ID,如果找到了则返回这个元素,如果没找到则返回null。

getElementsByTagName():接收一个参数,即要获取元素的标签名,返回包含零个或多个元素的NodeList。在HTML文档中,这个方法返回一个HTMLCollection对象。HTMLCollection与NodeList是相似的。如可以使用中括号item()方法从HTMLCollection取得特定的元素,也有length属性。HTMLCollection对象还有一个额外的方法namedItem(),可通过标签的name属性取得某一项的引用。

<img src="myimage.gif" name="myImage">

假设myImmage是获取文档上所有<img/>的节点,如果要获取文档中上面所示的代码,可以通过如下所示的代码来获取:

let myImage = images.namedItem("myImage");

即HTMLCollection提供了索引和namedItem()这两种方式来获取元素。其实对HTMLCollection对象而言,中括号既可以接收数值索引,也可以接收字符串索引。而在后台,数值索引会调用item(),字符串索引会调用namedItem()。 要取得文档中的所有元素,可以给getElementsByTagName()传入*,即

let allElements = document.getElementsByTagName("*");

getElementsByName():返回具有给定name属性的所有元素,返回的对象也是HTMLCollection,但要注意,这种情况下,namedItem()方法只会取得第一项(因为所有项的name属性都一样)。

2.4 特殊集合

document对象上还暴露了几个特殊集合,这些集合也都是HTMLCollection的实例。这些集合是访问文档中公共部分的快捷方式。

属性说明
anchors所有带name属性的<a>元素
forms所有<form>元素
images所有<img>元素
links所有带href属性的<a>元素

2.5 文档写入

向网页输出流中写入内容。对应有4个方法:write()、writeln()、open()和close()。 write()和writeln()方法都接收一个字符串参数,可以将这个字符串写入网页中。write()简单地写入文本,而writeln()还会在字符串末尾追加一个换行符(\n)
在页面渲染期间向文档写入内容:

        <p>This is some content that you won't get to see because it will be overwritten.</p>
    <script type="text/javascript">
        document.write("<strong>" + (new Date()).toString() + "</strong>");
    </script>

效果如下:

image.png 在页面加载完之后向文档写入内容:

        <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("<strong>" + (new Date()).toString() + "</strong>");
        };
    </script>

效果如下:

image.png
原来网页的内容已经没有了
open()和close()方法分别用于打开和关闭网页输出流。在调用write()和writeln()时,这两个方法都不是必需的。

3.Element类型

  • nodeName值为元素的标签名
  • nodeValue值为null
    nodeName或tagName属性来获取元素的标签名

3.1 取得属性

getAttribute():参数为元素的属性名,该方法也可以获取自定义的属性值。
元素的所有属性也可以通过相应DOM元素对象的属性来取得,通过DOM对象访问的属性中有两个返回的值跟使用getAttribute()取得的值不一样:

  • style属性:使用getAttribute()访问style属性时,返回的是CSS字符串。而在通过DOM对象的属性访问时,style属性返回的是一个(CSSStyleDeclaration)对象。DOM对象的style属性用于以编程方式读写元素样式,因此不会直接映射为元素中style属性的字符串值。
  • 事件处理程序(或者事件属性):使用getAttribute()访问事件属性,则返回的是字符串形式的源代码。而通过DOM对象的属性访问事件属性时返回的则是一个JavaScript函数(未指定该属性则返回null)

3.2 设置属性

setAttribute():接收两个参数:要设置的属性名和属性的值。如果属性已经存在,则setAttribute()会以指定的值替换原来的值;如果属性不存在,则setAttribute()会以指定的值创建该属性。适用于HTML属性,也适用于自定义属性
给DOM对象的属性赋值也可以设置属性,注意,在DOM对象上添加自定义属性,如下面的例子所示,不会自动让它变成元素的属性:

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

removeAttribute():从元素中删除属性

3.3 attribute属性

Element类型是唯一使用attributes属性的DOM节点类型。attributes属性包含一个NamedNodeMap实例,是一个类似NodeList的“实时”集合。元素的每个属性都表示为一个Attr节点,并保存在这个NamedNodeMap对象中。NamedNodeMap对象包含下列方法:

  • getNamedItem(name),返回nodeName属性等于name的节点
  • removeNamedItem(name),删除nodeName属性等于name的节点;
  • setNamedItem(node),向列表中添加node节点,以其nodeName为索引;
  • item(pos),返回索引位置pos处的节点。 attributes属性中的每个节点的nodeName是对应属性的名字,nodeValue是属性的值 访问属性,如:
    let id = element.attributes.getNamedItem("id").nodeValue;
    let id = element.attributes["id"].nodeValue;

即也可以使用中括号访问属性。同样,也可以使用中括号设置属性

3.4 创建元素

document.createElement():参数是要创建的元素的标签名。用这个方法创建的元素没有添加到文档树中。

4.Text类型

Text节点中包含的文本可以通过nodeValue属性访问,也可以通过data属性访问,这两个属性包含相同的值。修改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的文本。

4.1 创建文本节点

document.createTextNode():接收一个参数,即要插入节点的文本。插入的HTML代码会被转换为:

    <div id="app"></div>
    <script type="text/javascript">
        let div = document.getElementById('app');
        let textNode = document.createTextNode("<strong>Hello</strong> world");
        let textNode1 = document.createTextNode("<strong>eemmm</strong>");
        div.appendChild(textNode);
        div.appendChild(textNode1);
    </script>

效果:

image.png

在将一个文本节点作为另一个文本节点的同胞插入后,两个文本节点的文本之间不会包含空格。

4.2 规范文本结点

DOM文档中的同胞文本节点可能导致困惑,因为一个文本节点足以表示一个文本字符串。为此,可以使用normalize()合并相邻的文本节点。

normalize():在包含两个或多个相邻文本节点的父节点上调用该方法时,所有同胞文本节点会被合并为一个文本节点。

4.3 拆分文本节点

splitText(offset),在位置offset将当前文本节点拆分为两个文本节点;拆分之后,原来的文本节点包含开头到偏移位置前的文本,新文本节点包含剩下的文本。这个方法返回新的文本节点。

5.DocumentFragment类型(文档片段)

说明

DocumentFragment类型是唯一一个在标记中没有对应表示的类型,DOM将文档片段定义为“轻量级”文档,能够包含和操作节点

文档片段的作用是充当其他要被添加到文档的节点的仓库。可以使用document.createDocumentFragment()方法创建文档片段。

文档片段从Node类型继承了所有文档类型具备的可以执行DOM操作的方法。如果文档中的一个节点被添加到一个文档片段,则该节点会从文档树中移除,不会再被浏览器渲染。添加到文档片段的新节点同样不属于文档树,不会被浏览器渲染。

文档片段本身永远不会被添加到文档树

用法

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

假设想给这个<ul>元素添加3个列表项。如果分3次给这个元素添加列表项,浏览器就要重新渲染3次页面,以反映新添加的内容。为避免多次渲染,下面的代码示例使用文档片段创建了所有列表项,然后一次性将它们添加到了<ul>元素:

        let fragment = document.createDocumentFragment();
        let ul = document.getElementById("myList");
        for (let i = 0; i < 3; i++) {
            let li = document.createElement("li");
            li.appendChild(document.createTextNode(`Item ${i + 1}`));
            fragment.appendChild(li);
        }
        ul.appendChild(fragment);