第十章 DOM
Node类型
appendChild()
,用于向childNodes 列表的末尾添加一个节点。添加节点后,childNodes 的新增节点、父节点及以前的最后一个子节点的关系指针都会相应地得到更新。更新完成后,appendChild()返回新增的节点- 如果需要把节点放在childNodes 列表中某个特定的位置上,而不是放在末尾,那么可以使用
insertBefore()
方法。这个方法接受两个参数:要插入的节点和作为参照的节点。插入节点后,被插入的节点会变成参照节点的前一个同胞节点(previousSibling),同时被方法返回。如果参照节点是null,则insertBefore()与appendChild()执行相同的操作 replaceChild()
方法接受的两个参数是:要插入的节点和要替换的节点。要替换的节点将由这个
方法返回并从文档树中被移除,同时由要插入的节点占据其位置- 如果只想移除而非替换节点,可以使用
removeChild()
方法。这个方法接受一个参数,即要移除
的节点 cloneNode()
方法的两种模式。
var deepList = myList.cloneNode(true);
alert(deepList.childNodes.length); //3(IE < 9)或7(其他浏览器)
var shallowList = myList.cloneNode(false);
alert(shallowList.childNodes.length); //0normalize()
,这个方法唯一的作用就是处理文档树中的文本节点。由于解析器的实现或DOM操作等原因,可能会出现文本节点不包含文本,或者接连出现两个文本节点的情况。当在某个节点上调用这个方法时,就会在该节点的后代节点中查找上述两种情况。如果找到了空文本节点,则删除它;如果找到相邻的文本节点,则将它们合并为一个文本节点
Document类型
document.documentElement
属性,该属性始终指向HTML 页面中的<html>
元素- document.body属性,直接指向
<body>
元素。 - document.doctype属性
- title属性
URL、domain 和referrer
当页面中包含来自其他子域的框架或内嵌框架时,能够设置document.domain 就非常方便了。由
于跨域安全限制, 来自不同子域的页面无法通过JavaScript 通信。而通过将每个页面的
document.domain 设置为相同的值,这些页面就可以互相访问对方包含的JavaScript 对象了。例如,
假设有一个页面加载自www.wrox.com,其中包含一个内嵌框架,框架内的页面加载自p2p.wrox.com。
由于document.domain 字符串不一样,内外两个页面之间无法相互访问对方的JavaScript 对象。但如
果将这两个页面的document.domain 值都设置为”wrox.com”,它们之间就可以通信了。查找元素:getElementById()和getElementsByTagName()方法
注意js的位置,如果在head,会返回null,因为div还没加载。应放在body最后。
var images = document.getElementsByTagName(“img”);这行代码会将一个HTMLCollection 对象保存在images 变量中。与NodeList 对象类似,可以使用方括号语法或item()方法来访问HTMLCollection 对象中的项。而这个对象中元素的数量则可以通过其length 属性取得。HTMLCollection 对象还有一个方法,叫做namedItem(),使用这个方法可以通过元素的name特性取得集合中的项。
第三个方法,也是只有HTMLDocument 类型才有的方法,是getElementsByName()。顾名思义,这个方法会返回带有给定name 特性的所有元素。最常使用getElementsByName()方法的情况是取得
单选按钮;为了确保发送给浏览器的值正确无误,所有单选按钮必须具有相同的name 特性,如下面的
例子所示。document 对象还有一些特殊的集合。这些集合都是HTMLCollection 对象,
为访问文档常用的部分提供了快捷方式,包括:
document.anchors,包含文档中所有带name 特性的<a>元素;
document.applets,包含文档中所有的<applet>元素,因为不再推荐使用<applet>元素,
所以这个集合已经不建议使用了;
document.forms,包含文档中所有的<form>元素,与document.getElementsByTagName("form")
得到的结果相同;
document.images,包含文档中所有的<img>元素,与document.getElementsByTagName
("img")得到的结果相同;
document.links,包含文档中所有带href 特性的<a>元素。一致性检测
var hasXmlDom = document.implementation.hasFeature(“XML”, “1.0”);文档写入
<html> <head> <title>document.write() Example</title> </head> <body> <p>The current date and time is: <script type="text/javascript"> document.write("<strong>" + (new Date()).toString() + "</strong>"); </script> </p> </body> </html>
document.write("<script type=\"text/javascript\" src=\"file.js\">" +
对script标签要转义
"<\/script>");Element类型
tagName 元素的标签名
操作特性的DOM方法主要有三个,分别是getAttribute()、setAttribute()和removeAttribute()
根据HTML5 规范,自定义特性应该加上data-前缀以便验证
遍历输出一个元素的所有属性
function outputAttributes(element){
var pairs = new Array(),
attrName,
attrValue,
i,
len;
for (i=0, len=element.attributes.length; i < len; i++){
attrName = element.attributes[i].nodeName;
attrValue = element.attributes[i].nodeValue;
if (element.attributes[i].specified) {
pairs.push(attrName + "=\"" + attrValue + "\"");
}
}
return pairs.join(" ");
}var div = document.createElement(“div”);在使用createElement()方法创建新元素的同时,也为新元素设置了ownerDocuemnt 属性。此时,还可以操作元素的特性,为它添加更多子节点,以及执行其他操作。来看下面的例子。
div.id = “myNewDiv”;
div.className = “box”;
在新元素上设置这些特性只是给它们赋予了相应的信息。由于新元素尚未被添加到文档树中,因此设置这些特性不会影响浏览器的显示。要把新元素添加到文档树,可以使用appendChild()、insertBefore()
或replaceChild()方法。下面的代码会把新创建的元素添加到文档的元素中。
document.body.appendChild(div);Text类型
<!-- 没有内容,也就没有文本节点 --> <div></div> <!-- 有空格,因而有一个文本节点 --> <div> </div> <!-- 有内容,因而有一个文本节点 --> <div>Hello World!</div>
normalize
如果在一个包含两个或多个文本节点的父元素上调用normalize()方法,则会将所有文本节点合并成一个
节点,结果节点的nodeValue 等于将合并前每个文本节点的nodeValue 值拼接起来的值。来看一个
例子。
var element = document.createElement("div");
element.className = "message";
var textNode = document.createTextNode("Hello world!");
element.appendChild(textNode);
var anotherTextNode = document.createTextNode("Yippee!");
element.appendChild(anotherTextNode);
document.body.appendChild(element);
alert(element.childNodes.length); //2
element.normalize();
alert(element.childNodes.length); //1
alert(element.firstChild.nodeValue); // "Hello world!Yippee!"Text 类型提供了一个作用与normalize()相反的方法:splitText()。这个方法会将一个文本节
点分成两个文本节点,即按照指定的位置分割nodeValue 值。原来的文本节点将包含从开始到指定位
置之前的内容,新文本节点将包含剩下的文本。这个方法会返回一个新文本节点,该节点与原节点的
parentNode 相同。来看下面的例子。
var element = document.createElement("div");
element.className = "message";
var textNode = document.createTextNode("Hello world!");
element.appendChild(textNode);
document.body.appendChild(element);
var newNode = element.firstChild.splitText(5);
alert(element.firstChild.nodeValue); //"Hello"
alert(newNode.nodeValue); //" world!"
alert(element.childNodes.length); //2理解DOM的关键,就是理解DOM 对性能的影响。DOM操作往往是JavaScript 程序中开销最大的
部分,而因访问NodeList 导致的问题为最多。NodeList 对象都是“动态的”,这就意味着每次访问
NodeList 对象,都会运行一次查询。有鉴于此,最好的办法就是尽量减少DOM操作。