javascript高级程序设计第十章 DOM笔记

10.29更新:
原文中有个错误,childNodes在非IE浏览器中获得的不只是元素节点还会有文本节点,用childNodes去获取元素节点往往会得不到自己想要的结果,所以建议少用childNodes。多用children,children只会获取元素节点。


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

10.1 节点层次

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

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

10.1.1 Node类型

DOM1级定义了一个Node接口,该接口将由DOM中的所有节点类型实现

这个Node接口在JavaScript中是作为Node类型实现的

JavaScript中的所有节点类型都继承自Node类型,因此所有节点类型都共享着相同的基本属性和方法。每个节点都有一个nodeType属性,用于表明节点的类型

(12个节点类型的数值常量见书p248)

if(someNode.nodeValue == 1){
//也可使用someNode.nodeValue == Node.ELEMENT_NODE,但是这个不适用IE浏览器
    alert("Node is an element);
}

1. nodeName和nodeValue属性
这两个属性可了解节点的具体信息,在使用这两个属性之前最好先判断一下节点的类型

if(nodeType == 1){
    var value = someNode.nodeName;
}

元素的nodeName是标签名,nodeValue是null

2.节点关系

<html>
<head>
    <style>
    </style>
</head>
<body>
    <div id="container">
    	<ul id="list">
    		<li></li>
			<li></li>
    	</ul>
		<img src="#" />
		<a></a>
    </div>
</body>
</html>

以上html代码作为例子用来分析节点关系

所以可得关系图
在这里插入图片描述
每个节点都有一个childNodes属性,其中保存着一个NodeList对象。NodeList是一种类数组对象,用于保存一组有序的节点,可通过位置来访问这些节点。(这个对象不是Array实例)

访问保存在NodeList中的节点,可通过数组的方法也可通过item(),但是推荐使用数组方法

var firstChild = parentNode.childNodes[0];
//也可用var firstChild = parentNode.childNodes.item(0);
var count = parentNode.childNodes.length;
//返回子节点个数

且parentNode.childNodes[0];可用parentNode.firstChild;代替
parentNode.childNodes[parentNode.childNodes.length-1]可用parentNode.lastChild代替

若父节点下只有一个子节点,则parentNode.firstChild和parentNode.lastChild的值相等
没有子节点,则它两个的值都为0

每个节点都有一个parentNode属性,指向该节点的父节点

还有两个属性previousSibling和nextSibling,前者指向该节点的前一个同胞节点,后者指向该节点的后一个同胞节点

上面的例子中ul,img,a三个元素所代表的节点就互为同胞节点,两个li也是互为同胞节点

hasChildNodes()方法可查询一个节点是否有子节点,有则返回true

ownerDocument属性指向表示整个文档的文档节点

3.操作节点

appendChild()方法:向childNodes列表末尾添加一个节点
若添加的节点是原有节点,那么就将该原有节点调换到列表的最后一个位置

insertBefore()方法:将节点插入到childNodes列表中某个特定位置上
接收两个参数,第一个是被插入的节点,第二个是参考节点。被插入节点会插入到参考节点前面一位。

replaceChild()方法:将原有节点替换成另一个节点
接受两个参数,第一个是要替换上去的节点,第二个是要被替换的节点。

removeChild()方法:移除某个节点
接受一个参数,要被移除的节点

前面的四个方法,都是操作某个父节点的子节点,所以说使用方法前要先取得父节点。例如父节点.appendChild(新的子节点);
4.其他方法
cloneNode()方法:创建调用这个方法的节点的副本
接受一个布尔值参数,true执行深复制(赋值节点及其整个子节点树),false执行浅复制,只复制该节点

这个副本在文档中,但它没有父节点,所以就像个“孤儿”一样没有自己的位置,如果想让他有自己的位置,就要用到前面的一些方法了

normalize()方法:处理文档树中的文档节点
本章后面会进一步讨论该方法
(未完待续)

10.1.2 Document类型

跳转到最常用的Document类型1
跳转到最常用的Document类型2

JavaScript通过Document类型表示文档

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

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

(Document节点的特征见书上p253)

1.文档的子节点

documentElement属性:该属性始终指向<html>元素
document.documentElement、document.childNodes[0]、document.firstChild都是指向<html>元素

body属性:直接指向<body>元素

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

2.文档信息
titile属性:包含着<title>元素中的文本(显示在浏览器窗口的标题栏或标签栏上)
修改title属性的值可改变<title>元素的文本内容

var title = document.title;
document.title = "yuan";    //修改标题,那么变量title的值也会跟着修改

URL属性:包含页面完整的URL
完整的URL:http://www.wrox.com/WileyCDA/

domain属性:只包含页面域名
页面域名:www.wrox.com

referrer属性:保存着链接到当前页面的那个页面的URL
在没有来源页面的情况下,该属性会包含空字符串

在这三个属性中只有domain是可以设置的,但是不能将这个属性设置为URL中不包含的域

//页面来自p2p.wrox.com域
document.domain = wrox.com;
document.domain = baidu.com;    //错误

3.查找元素

getElementById()方法:按照元素的ID查找元素
不存在则返回null。若页面中有多个拥有相同ID的元素,则只返回文档中第一次出现的元素

getElementsByTagName()方法:根据元素标签查找元素
返回的是一个类似数组的动态集合对象HTMLCollection(下面的几个方法都会返回这样一个对象),和前面的childNodes有点像

var images = document.getElementsByTagName("img");
consolo.log(images[0].src);    //输出images下第一个img元素的src特性
console.log(images.item(0).src);    //用item()方法也是可以的

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

console.log(images.namedItem("myImage"));    //在HTMLCollection对象取得name为myImage的元素
console.log(images["myImage"]);    //更简单的方法

因为在JavaScript和CSS中 * 通常表示全部

//访问文档中的所有元素
var allElements = document.getElementsByTagName("*");

getElementsByName()方法:返回带有给定name特性的所有的元素
最常使用此方法的情况是取得单选按钮

getElementsByClassName()方法:返回给定的class特性的元素

4.特殊集合(p258)

5.DOM一致性检测(p259)

6.文档写入

document.write();将方法中的字符串内容原样写入

document.writeln();将字符串内容写入后再添加一个换行符

两种方法还可动态地添加外部资源

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

10.1.3 Element 类型

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

Element节点特性(p261)

访问元素标签名,可使用nodeName属性或是tagName属性,两属性返回相同的值,但鉴于理解性,最好用后者

var div = document.getElementById("myDiv");
console.log(div.tagName);    //DIV

返回DIV而不是div是因为再HTML中标签名是用大写字母表示,所以

if(div.tagName == "div"){ }    //不能这样比较,要用下面这种
if(div.tagName.toLowerCase() == "div"){ }

1.HTML元素

一个特殊且有用的标准特性:
title 有关元素的附加说明信息,把鼠标停留再这个元素上一会儿他会自动显现出来

(其余部分见 p262-p264)

2.取得特性

getAttribute()方法:取得元素的特性

var div = document.getElementById("myDiv");
console.log(div.getAttribute("id"));    //取得mydiv这个元素的ID属性

通过此方法也可取得自定义属性(自定义属性应该加上data-前缀以便验证)
自定义属性不会自动成为元素得特性;

开发人员不常用getAttribute(),而是只使用对象的属性。只有在取得自定义特性值得情况下才会使用getAttribute()方法

3.设置特性
setAttribute()方法:设置元素得特性,公认特性和自定义属性均可设置
接受两个参数,要设置得特性名和值。若特性已存在则会替换原有特性得值,不存在则重新创建

div.setAttribute("id","yuan");
div.id = "yuan";    //两者效果相同

4.attributes属性(没太看懂,但也用的不多)
Element类型是使用attributes属性得唯一一个DOM节点类型。attributes属性中包含一个NamedNodeMap,与NodeList类似,也是一个”动态“的集合

5.创建元素
createElement()方法可创建新元素,这个方法接受一个参数,即要创建的元素的标签名

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

以上分为三步,创建一个新的元素,为这个元素添加一些特性,再将这个元素添加进文档树中
那么这个元素就真的进入文档树之中了,就能再网页中显示出来了

6.元素的子节点
不同浏览器对一个元素到底有多少子节点的定义不同,详见p269-p270

10.1.4 Text类型

文本节点由Text类型表示,包含的是纯文本内容

nodeName的值是"#text",nodeValue的值为节点所包含的文本

开始与结束标签之间有文本才算有文本节点,一个空格也算文本节点

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

//创建一个div标签的新元素
var element = document.createElement("div");
var text = document.createTextNode("Hello yuan");
//将这个文本节点放到元素下,这样才能在网页中正常显示
element.appendChild(text);
//将新建的元素节点放到body中
document.body.appendChild(element);

2.合并多个文本节点
normalize()方法:父元素调用normalize()方法可将其下面的多个文本节点合并到一起

var element = document.createElement("div");
var text = document.createTextNode("Hello");
element.appendChild(text);
var anotherText = document.createTextNode(" yuan");
elemnt.appendChild(anotherText);
document.body.appendChild(element);
console.log(element.childNodes.length);    //1(合并为一个了)
console.log(element.firstChild.nodeValue);    //Hello yuan

3.splitText()方法:此方法由文本节点调用,接受一个参数(从哪个位置开始分割),并且返回一个新的文本节点,此节点与原节点有同样的父节点

分割文本节点是一种常用的DOM解析技术

var element = document.createElement("div");
var text = document.createTextNode("Hello yuan");
element.appendChild(text);
document.body.appendChild(element);
//从第5个位置即空格开始分割文本节点
var newText = element.firstChild.splitText(5);

10.1.5 Comment类型

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

10.1.6 ——10.1.9

(p274-p277)

10.2 DOM 操作技术

(p277-p284)

10.3 小结

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

理解DOM的关键就是理解DOM对性能的影响。DOM操作往往是js程序中开销最大的部分,因此访问NodeList导致的问题最多。NodeList对象都是”动态的”,这就意味着每次访问NodeList对象,都会运行一次查询,所以最好减少DOM操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值