DOM

10.1 节点层次

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

<html>
        <head>
            <title>Sample Page</title>
        </head>
        <body>
            <p>Hello World!</p>
        </body>
</html>

文档节点是每个文档的根节点。在上述例子中,文档节点只有一个子节点,即<html>,我们称之为文档节点。

文档节点是文档的最外层元素,文档中的其他所有元素都包含在文档元素中。每个文档只能有一个文档元素。

10.1.1 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.COMMENY_NODE(8);

Node.DOCUMENT_NODE(9);

Node.DOCUMENT_TYPE_NODE(10);

Node.DOCUMENT_FRAGMENT_NODE(11);

Node.NOTATION_NODE(12);

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

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

1、nodeName和nodeValue属性

要了解节点的具体信息,可以使用nodeName和nodeValue这两个属性。这两个属性的值完全取决于节点的类型。在使用这两个值以前,最好是先检测下节点的类型

如果节点是一个元素,nodeName中保存的始终都是元素的标签名,而nodeValue的值始终是null。

2、节点关系

文档中所有的节点之间都存在这样或那样的关系。

每个节点都有一个childNodes属性,其中保存着一个NodeList对象。NodeList是一种类数组对象,用于保存一组有序的节点,可以通过位置来访问这些节点。请注意,虽然可以通过方括号语法来访问NodeList的值,而且这个对象也有length属性,但是它并不是Array的实例。NodeList对象的独特之处在于,它实际上是基于DOM结构动态执行查询的结果,因此DOM结构的变化能够自动反映在NodeList对象中。我们常说,NodeList是有生命、有呼吸的对象,而不是在我们第一次访问它们的某个瞬间摆着的一张快照。

访问保存在NodeList中的节点——可以通过方括号,也可以使用item()方法

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

节点间关系图

hasChildNodes()是一个非常有用的方法。

3、操作节点

(1)appendChild()用于项childNodes列表的末尾添加一个节点。更新完成后,appendChild()返回新增的节点。

var returnedNode = someNode.appendChild(newNode);
alert(returnedNode == newNode);          //true
alert(someNode.lastChild == newNode);    //true

注意:如果传入到appendChild()中的节点已经是文档的一部分了,那结果就是将该节点从原来的位置转移到新的位置。即使可以将DOM树看作是由一系列指针连接起来的,但任何DOM节点也不能同时出现在文档的多个位置上。因此,如果在调用appendChild()时传入了父节点的第一个子节点,那么该节点就会成为父节点的最后一个子节点,

var returnedNode = someNode.appendChild(someNode.firstChild);
alert(returnedNode == someNode.firstChild);   //false;
alert(returnedNode == someNode.lastChild);   //true;

(2)insertBefore()方法,接收两个参数:要插入的节点和作为参照的节点。插入节点后,被插入的节点会编程参照节点的前一个同袍节点,同时被方法返回。如果参照节点是null,则insertBefore()与appendChild()执行相同的操作。

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

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

//插入到最后一个子节点的前面

returnedNode = someNode.insertBefore(newNode,someNode.lastChild);
alert(newNode == some.childNodes[someNode.childNodes.length-2]); //true

(3)replaceChild()方法接受的两个参数是:要插入的节点和要替换的节点。要替换的节点将由这个方法返回并从文档树中被移除。

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

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

(4)removeChild()移除某个节点。接受一个参数,即要移除的节点

//移除第一个节点
var
returnedNode = someNode.removeChild(someNode.firstChild); //移除最后一个节点 var returnedNode = someNode.removeChild(someNode.lastChild);

(5)cloneNode()用于创建调用这个方法的节点的一个完全相同的副本。cloneNode()方法接受一个布尔值参数,表示是否执行深复制。在参数为true的情况下,执行深复制,即复制节点及整个子节点树;在参数为false的情况下,执行浅复制,即只复制节点本身。复制后的节点副本属于文档所有,但并没有为它指定父节点。除非通过appendChild()、insertBefore()或replaceChild()将它添加到文档中。

10.1.2 Document类型

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

Document节点具有下列特征:

nodeType的值是9;

nodeName的值为“#document”;

nodeValue的值是null;

parentNode的值为null;

ownerDocument的值为null;

(1)文档的子节点

有两个内置的访问Document节点的子节点快捷方式。第一个就是documentElement属性,该属性始终指向HTML页面中的<html>元素。另一个就是通过childNodes列表访问文档元素,但通过documentElement属性更快捷、更直接。

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

这个页面在经过浏览器解析后,其文档中只包含一个子节点,即<html>元素。可以通过documentElement或childNodes列表来访问这个元素

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

document对象还有一个body属性,直接指向<body>元素。

var body = document.body;

Document的另一个可能的子节点是DocumentType。通常将<!DOCTYPE>标签看成一个与文档其他部分不同的实体,可以通过doctype属性来访问它的信息

var doctype = document.doctype;

由于浏览器对document.doctype的支持不一致,因此这个属性的用处很有限。

(2)文档信息

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

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

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

与网页请求有关的3个属性:URL、domain和referrer。URL属性中包含页面完整的URL(即地址栏中显示的URL),domain属性中只包含页面的域名,而referrer属性中则保存着链接到当前页面的那个页面的URL。在没有来源页面的情况下,referrer属性中可能会包含空字符串。所有这些信息都存在于请求的HTTP头部。

//取得完整的URL
var url = document.url;
//取得域名
var domain = document.domain;
//取得来源页面的URL
var url = document.referrer;

这三个属性,只有domain是可以设置的。但由于安全考虑,也并非可以给domain设置任何值。如果URL中包含一个子域名,例如p2p.wrox.com,那么就只能将domain设置为“wrox.com”.不能将这个属性设置为URL中不包含的域

(3)查找元素

1、getElementById(),接收一个参数:要取得的元素的ID。

注意:IE8以及低版本不区分ID的大小写,因此“myDiv”和“mydiv”会被当做相同的元素ID。

如果页面中多个元素的ID值相同,getElementById()只返回文档中第一次出现的元素。IE7及较低版本还为此方法添加了一个有意思的“怪癖”:name特性与给定ID匹配的表单元素也会被该方法返回。如果有哪个表单元素的name特性等于指定的ID,而且该元素在文档中位于带有给定ID的冤死前面,那么IE就会返回那个表单元素。

<input type="text" name="myElement" value="Text field">
<div id="myElement">A div</div>

基于上述代码,在IE7中调用document。getElementById("myElement"),结果会返回<input>元素;而在其他浏览器中,都会返回对<div>元素的引用。

2、getElementsByTagName();接收一个参数:即要取得元素的标签名,而返回的是包含零或多个元素的NodeList。

var images = document.getElementsByTagName("img");

与NodeList对象类似,可以使用方括号语法或者item()方法来访问HTMLCollection对象中的项。而这个对象中元素的数量则可以通过其length属性取得

alert(images.length);  //输出图像的数量
alert(images[0].src);   //输出第一个图像元素的src特性
alert(images.item(0).src);   //输出第一个图像元素的src特性

HTMLCollection对象还有一个方法,叫做namedItem(),使用这个方法可以通过元素的name特性取得集合中的项。

<img src="myimage.gif" name="myImage" >
可以通过以下方式从images变量中取得这个<img>元素
var myImage = images.namedItem("myImage");
对命名的项也可以使用方括号语法来访问
var myImage = images.namedItem{["myImage"];

可以向getElementsByTagName()中传入“*”。在JavaScript及css中,星号(“*”)通常表示全部。

var allElements = document.getElementsByTagName("*");包含整个页面的所有元素——按照它们出现的先后顺序。

3、getElementsByName()这个方法会返回带有给定name特性的所有元素

4、特殊集合

document.anchors  包含文档中所有带name特性的<a>元素

document.forms 包含文档中所有的<form>元素,与document.getElementsByTagName("form")得到的结果相同

document.images 包含文档中所有的<img>元素,与document.getElementsByTagName("img")得到的结果相同

document.links 包含文档中所有带href特性的<a>元素

10.1.3 Element类型

Element类型是Web编程中最常见的类型了。Element类型用于表现XML或HTML元素,提供对元素标签名、子节点及特性的访问。

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

<div id="myDiv"></div>

var div = document.getElementById("myDiv");
alert(div.tagName);  //"DIV"
alert(div.tagName == div.nodeName);  //true;

1、取得特性

每个元素都有一个或多个特性,这些特性的用途是给出相应元素或其内容的附加信息。操作特性的DOM方法有三个:getAttribute()、setAttribute()、removeAttribute()

var div = document.getElementById("myDiv");
alert(div.getAttribute("id"));  //"myDiv"
alert(div.getAttribute("class"); // "bd"

2、设置特性

与getAttribute()对应的方法是setAttribute()。这个方法接受两个参数:要设置的特性名和值。

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

3、删除特性

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

div.removeAttribute("class");

4、attributes属性

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

用处:

如果想要遍历元素的特性,attributes属性可以使用

for(var i = 0;i < element.attributes.length;i++){
  attrName = element.attributes[i].nodeName;
  attrValue = element.attributes[i].nodeValue;
}

5、创建元素

document.createElement()可以创建新元素

var div = document.createElement("div");

6、元素的子节点

使用children、firstElementChild、lastElementChild、nextElementSlibling、parentNode可以取得element元素,避免其他类型节点

10.1.4 文本节点

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

1、创建文本节点

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

var element = document.createTextNode("<strong>Hello</strong>world!");

var element = document.createTextNode("Hello world!");

2、规范化文本节点

DOM文档中出现相邻文本节点的情况也不在少数,有一个将相邻文本节点合并的方法,normalize()。如果在一个包含两个或多个文本节点的父元素上调用normalize()方法,则会将所有文本节点合并成一个节点。

var element = document.createElement("div");
element.className = "message";

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

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

document.body.appendChild(element):

element.childNodes.length; //2

element.normalize();
element.childNodes.length; //1

3、分割文本节点

var element = document.createElement("div");
element.className = "message";

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

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

document.body.appendChild(element):

var newNode = element.firstChild.splitText(5);
element.firstChild.nodeValue = "Hello";
newNode.nodeValue;  //" World";

element.childNodes.length; //2

10.1.8 DocumentFragment类型

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

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

var fragment = document.createDocumentFragment();

var ul = document.createElement("div");
var li = null;

for(var i = 0;i < 3;i++){
li = document.createElement("li");
li.appendChild(document.createTextNode("Item "+(i+1)));
frament.appendChild(li);
}

ul.appendChild(fragment);
原文地址:https://www.cnblogs.com/deerfig/p/7341423.html