DOM可以将任何HTML或XML文档描绘成一个有多层节点构成的结构,即在HTML中所有内容都是节点。文档节点是每个文档的根节点,文档节点有一个子节点,称为文档元素。每个文档只能有一个文档元素。在HTML中,文档元素是<html>元素,其他所有元素都包含在文档元素中。
1、节点
JavaScript中实现了一个 Node 类型来描述DOM节点,JavaScript中的所有节点类型都是继承自Node类型。一共有12中节点类型,Node类型定义了12个数值常量来表示,如下所示,其中括号中表示的是常量的值,除了IE都可以使用下列常量名访问这些值。
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 | 节点类型,返回类型数值 |
nodeName | 节点名字,对于元素节点,返回的是元素的标签名 |
nodeValue | 节点值,对于元素节点,返回null |
childNodes |
子节点,返回一个NodeList对象 |
parentNode | 父节点 |
previousSibling | 前面一个同胞节点 |
nextSibling | 后面一个同胞节点 |
firstChild | 第一个子节点 |
lastChild | 最后一个子节点 |
hasChildNodes() | 如果有子节点,返回true,反之,false |
appendChild(newNode) | 向childNodes列表末尾添加一个节点 |
insertBefore(newNode,targetNode) | 在目标子节点前插入新子节点,如果targetNode为null,新节点成为最后一个节点 |
replaceChild(newNode,targetNode) | 用新节点替换目标节点 ,替换后,被替换的节点仍在文档中,但没有文档位置 |
removeChild(targetNode) | 移除目标节点 ,移除后,被移除的节点仍在文档中,但没有文档位置 |
cloneNode(isDeep) | 是否深度复制节点,深度复制会将子节点一起复制。复制完后节点属于文档,但没有父节点,需要通过 appendChild()、insertBefore()、replaceChild() 将它添加到文档中。 |
normalize() | 处理文档树的文本节点,删除空文本节点,或合并相邻的文本节点成为一个文本节点 |
NodeList是一种类似数组的对象,用于保存一组有序的节点,它有 length 属性,可以通过方括号语法来访问,也可以用item()方法。NodeList 对象是基于DOM结构动态执行查询的结果,DOM的变化,其中节点的NodeList也会变化。
var firstChild = someNode.childNodes[0];
var secondChild = someNode.childNodes.item(1); //
var count = someNode.childNodes.length;
2、Document 类型,document对象
Document类型表示文档,在浏览器中 document 对象时 HTMLDocument (继承自 Document 类型)的一个实例,表示整个页面,且 document 对象是 window 对象的一个属性。
Document节点的子节点可能是一个DocumentType(最多一个)、Element(最多一个)、ProcessingInstruction 或 Comment。
Document节点的属性及方法:
nodeType | 9 |
nodeName | #document |
nodevalue | null |
parentNode | null |
ownerDocument | null |
documentElement | 指向Html页面中的<html>元素 ,document.documentElement |
chilidNodes | |
doctype | 文档类型,<!DOCTYPE >,document.doctype。各个浏览器对此支持差别很大,用处有限 |
getElementById(ID) | 返回文档中第一次出现的、id属性匹配的元素,没有则返回null。IE9-不区分大小写,IE7中name属性匹配,也会被返回。 |
getElementsByTagName(tagName) | 返回包含所有匹配指定标签名元素的HTMLCollection对象,HTMLCollection与NodeList类似,有length属性,可以用方括号或item()访问 |
HTMLDocument类型的属性及方法:
getElementsByName(name) | 返回包含指定name属性的元素的NodeList对象 |
document 对象的属性及方法:
body | 直接指向<body>元素,document.body |
title | 取得文档的<title>元素中的文本,也可以设置title文本 |
URL | 完整的URL,即地址栏中显示地URL |
domain |
取得域名,也可设置域名,但只能将其设置为URL中包含的域。当页面包含有其他子域的框架或内嵌框架时,可以将这些页面的document.domain设置为相同的值, 这样就可以互相访问 js 对象了,即实现主域和子域之间的跨域。 |
referrer | 页面来源URL,没有页面来源则为空字符串 |
anchors | 返回包含所有带name属性的<a>元素的HTMLCollection 对象 |
forms | 返回包含所有<form> 元素的HTMLCollection 对象,等同于document.getElementsByTagName("from") |
images | 返回包含所有<img> 元素的HTMLCollection 对象,等同于document.getElementsByTagName("img") |
links | 返回包含所有带 href 属性的<a>元素的HTMLCollection 对象 |
write(string) | 向页面写入输出流 |
writeln(string) | 向页面写入输出流,并在字符串末尾加一个换行符 |
open() | 打开页面的输出流 |
close() | 关闭页面的输出流 |
createElement(elementTag) | 创建元素节点 |
createTextNode(text) | 创建文本节点 |
利用 document.domain 主域和子域跨域:
http://www.cnblogs.com/adtxgc/p/4691872.html
https://www.jianshu.com/p/4a3bc6d195b0?appinstall=0
可以利用document.write() 和 document.writeln() 动态地项页面加入内容
<script>
document.write("<script src=\"js/test.js\" type=\"text/javascript\"><\/script>"); </script>
如果在文档加载结束后再调用document.write(),那么输出的内容将会重写整个页面
window.onload = function(){
document.write("hello world!")
}
在页面加载期间使用 document.write() 和 document.writeln(),不需要使用 document.open() 和 document.close() 。
HTMLCollection属性及方法
HTMLCollection.length | 对象中元素的数量 |
HTMLCollection.item(index) | 索引为index的项 |
HTMLCollection[index] | 索引为index的项 |
HTMLCollection.namedItem(name) | 第一个name属性匹配的项 |
HTMLCollection[name] | 第一个name属性匹配的项 |
var images = document.getElementsByTagName("img");
console.log(images.length);
console.log(images[0].src);
console.log(images.item(0).src); var myImage = images.namedItem("myImage");
var myImage1 = images["myImage"]; var allElements = document.getElementsByTagName("*"); //获取所有元素,在IE中注释节点也会包含进去
NodeList 、NamedNodeMap、HTMLCollection 这三个集合都是动态的,每当文档结构发生变化它们都会得到更新,所以它们始终保存的是最新的内容。
var divs = document.getElementsByTagName("div");
for (i=0;i< divs.length;i++){ //如果一开始divs.length大于零,会无限循环
div = document.createElement("div");
document.body.appendChild(div);
}
3、Element类型
nodeType | 1 | |
nodeName | 元素的标签名,在HTML中,得到的值是大写的;在XML中标签名与源代码一致 | |
nodeValue | null | |
parentNode | 可能是Document 或 Element | |
子节点 | 可能是Element、Text、ProcessingInstruction、CDATASection、EntityReference | |
tagName | 元素的标签名,值与nodeName一样 | element.tagName.toLowerCase == "div" |
所有的HTML元素都是有HTMLElement类型或其子类型表示的,而HTMLElement类型是直接继承Element类型并添加了一些属性。
id | 元素在文档中的唯一标识符,element.id |
可以获取属性或设置属性: var id = element.id; element.id = "someId"; |
||||||||||
title | 元素的附加说明信息 | 可以获取属性或设置属性 | ||||||||||
lang | 元素语言,很少使用 | 可以获取属性或设置属性 | ||||||||||
dir | 语言方向,“ltr”(left-to-right) / "rtl"(right-to-left) | 可以获取属性或设置属性 | ||||||||||
className | CSS类 | 可以获取属性或设置属性 | ||||||||||
getAttribute("attr") | 获取属性值,包括DOM本身属性,及自定义属性 | getAttribute("class"),不是“className” | ||||||||||
setAttribute("attr","value") | 设置属性值,包括DOM本身属性,及自定义属性 | 替换已存在的、新建不存在的,属性名会变成小写 | ||||||||||
removeAttribute("attr") | 移除属性 | |||||||||||
attributes |
返回一个包含该元素所有属性节点的NamedNodeMap对象 NamedNodeMap 和 NodeList 类似,是一个动态集合。 attributes包含的节点的nodeName是属性节点的名称 nodeValue是属性节点的值. attributes可以用来遍历元素的属性 |
NamedNodeMap:
element.attributes["id"].nodeName //可以获取属性或设置属性 element.attributes["id"].nodeValue //可以获取属性或设置属性 element.attributes.removeNamedItem("class") |
||||||||||
直接访问元素的属性(element.attr)和 使用 getAttribute() 的区别:
1) 直接属性访问只能访问该DOM元素本来就有的属性,但IE却会为自定义的文档属性也创建元素对象的属性,即能够通过element.specialAttribute 访问,其他浏览器不会。
2)访问 style 属性:直接属性访问(element.style)返回一个对象,getAttribute() 返回的是style中包含的CSS文本。
3)访问事件处理程序,如 onclick :直接属性访问(element.onclick)返回的是一个JavaScript函数(如果没有相应的属性,返回null),getAttribute() 返回的是 JavaScript 代码
通常在访问DOM本身就存在的属性,使用直接属性访问,而访问自定属性使用getAttribute()。
attributes
1)attributes 对象中得到的属性节点顺序,在各个浏览器中表现不一致
2)IE7及IE7- 版本中,会返回HTML元素所有的属性,包括没有指定的属性。
每个属性节点都有一个 specified 属性,如果 指定了该属性,则其 specified 的值为 true ,反之为 false。
//以 name="value" name="value" 返回dom元素的属性
function outputAttributes(element){
var pairs = [],
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){ // 处理IE8- 会出现的问题 pairs.push(attrName + "=\"" + attrValue + "\"");
}
} return pairs.join(" ");
}
创建元素节点:document.createElement(tagName),接受标签名参数
var testDiv = document.getElementById("test");
var div = document.createElement("div");
div.id = "newDiv"; document.body.insertBefore(div,testDiv);
元素子节点
<ul id="list">
<li class="a">item 1</li>
<li>item 2<span class="a">span</span></li>
<li>item 3</li>
</ul>
<ul id="list1"><li>item 1</li><li>item 2</li><li>item 3</li></ul> var testList = document.getElementById("list");
var testList1 = document.getElementById("list1"); console.log(testList.childNodes.length); // IE6、7、8浏览器是3;其他是7,3个li节点,4个文本节点(空白符)
console.log(testList1.childNodes.length); //所有浏览器是3 for(var i=0,len = testList.childNodes.len;i<len;i++){ if(testList.childNodes[i].nodeType == 1){
// 是元素节点,执行操作
}
} var li = testList.getElementsByTagName("li"); // 从后代元素中查找,HTMLCollection集合
var lia = testList.getElementsByClassName("a"); //从后代元素中查找,IE6、7、8不支持,HTMLCollection集合
4、Text 类型
文本节点,包含的是纯文本,可以是转义后的HTML字符,但不能是HTML代码。
nodeType | 3 | |
nodeName | "#text" | |
nodeValue | 节点包含的文本 | |
parentNode | 是一个Element | |
没有子节点 | ||
data | 等同nodeValue | |
length | 文本节点的字符长度,nodeValue.length,data.length 也有一样的值 | |
appendData(text) | 将文本添加到文本节点末尾 | |
deleteData(offset,count) | 从offset位置开始删除count个字符 | |
insertData(offset,text) | 从offset位置开始插入text | |
replaceData(offset,count,text) | 用text替换从offset开始的count个字符 | |
splitText(offset) | 从offset开始将当前文本分开两个文本节点,原节点包含指定位置之前的内容,新节点是之后的内容,并返回新节点 | |
substringData(offset,count) | 返回从offset开始的count个字符,不改变文本节点本身 | |
创建文本节点 document.createTextNode(text)
var textNode = document.createTextNode("<strong>someother text</strong>"); // 在页面中显示 “<strong>someother text</strong>”,并不会加粗显示“someother text”
testList.childNodes[1].appendChild(textNode);