DOM

Node类型

1.元素属性:

nodeName:元素的标签名tagName

nodeValue

2.节点关系:

childNodes属性:保存着一个NodeList对象,NodeList是一种类数组对象,用于保存一组有序的节点,可以通过位置来访问这些节点。

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

可以通过对arguments对象使用Array.prototype.slice()方法可以将其转化为数组。采用同样的方法,也可以将NodeList对象转化为数组。

var arrayOfNodes = Array.prototype.slice.call(someNode.childNodes,0);//IE8+

兼容性的:

function convertToArray(nodes){
	var array = null;
	try{
		array = Array.prtotype.slice.call(nodes,0);
	}catch(ex){
		array = new Array();
		for(var i = 0, len = nodes.length; i < len; i++){
			array.push(nodes[i]);
		}
	}
	return array;
}

parentNode属性:

该属性指向文档树中的父节点。

previousSibling属性:同胞节点上一个

nextSibling属性:同胞节点下一个

firstChild属性

lastChild属性

hasChildNodes()方法:有子节点返回true,比查询childNodes列表的length属性更简单。

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

3.操作节点

(1)插入节点

appendChild()用于向childNodes列表的末尾添加一个节点。

insertBefore()两个参数:要插入的节点,作为参照的节点。插入到被参照节点的前一个位置,同时将插入节点返回。

(2)移除节点

replaceChild()方法:两个参数:要插入的节点,要替换的节点。要替换的节点将由这个方法返回并从文档树中被移除,同时由要插入的节点占据其位置。

removeChild()方法。这个方法接收一个参数:要移除的节点。被移除的节点作为返回值。

4.其他方法

cloneNode(),用于创建调用这个方法的节点的一个完全相同的副本。

接收一个参数:true:执行深复制,也就是复制节点和其整个子节点数; false:执行浅复制,即只复制节点本身。

复制的节点没有父节点。孤儿

可用过appendchild()、insertBefore()、replaceChild()添加到文档中。

normalize():唯一的作用就是处理文档树中的文本节点。由于解析器的实现或DOM操作等原因,可能会出现文本节点不包含文本,或者接连出现链各个文本节点的情况。如空文本节点,则删除;如找到相邻的文本节点,则将他们合并为一个文本节点。

Document类型

1.文档的子节点

documentElement属性,该属性始终指向HTML页面中的<html>元素

var html = document.documentElement;

body属性,指向<body>

var body = document.body;

doctype属性,来访问<!Document>标签的信息

var doctype = document.doctype;

不同浏览器的支持性不同,用处有限。

2.文档信息

title属性

var originalTitle = document.title;//获取文档标题
document.title = "New page title";//设置文档标题

URL属性:包含页面完整的URL domain属性:只包含页面的域名 referrer属性:保存着连接到当前页面的那个页面的URL,如果没有,空字符串。

所有这些信息都保存与请求的HTTP头部,通过js访问他们。

3.查找元素

getElementById()

不让表单的name与其他元素的ID相同;对于IE7的怪癖

getElementByTagName()

返回的是包含0个或多个元素的NodeList。会返回一个HTMLCollection对象,作为一个“动态”集合,该对象与NodeList类似。

HTMLCollection对象:

item()方法来访问HTMLCollection对象中的项。数量通过length属性取得。

namedItem()方法,可以通过元素的name特性取得集合中的项。

getElementByName()

只有HTMLDocument类型才有这个方法,这个方法返回带有给定name特性的所有元素。为一个HTMLCollection对象。

4.特殊集合

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

5.DOM一致性检测

document.implementation属性提供了相应信息和功能的对象,与浏览器的dom实现直接对应。

document.implementation.hasFeature()接收两个参数:DOM功能的名称,版本号。如果支持给定的版本名称和版本功能,则该方法返回true.

document.implementation.hasFeature('XML','1.0');

6.文档写入

document.write();
document.writeln();//换行

在页面加载的过程中,可以使用这两个方法向页面动态地加入内容。

可加载字符串、变量、html元素(会创建一个DOM元素)

还可以使用这两个方法动态的包含外部资源,例如js文件等。在包含js文件时,不能直接写</script>,会导致该字符串被解释为脚本块的结束,导致他后面代码无法执行。

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

需要转义!

注意

使用document.write()在页面被呈现的过程中直接向其中输入了内容。如果在文档加载结束后再调用document.write(),那么输出的内容将会重写整个页面。

<script type="text/javascript">
	window.onload = function(){//等到页面加载完成后执行函数
		document.write("hello world");
	}
 </script>


document.open();//打开网页的输入流
document.close();//关闭网页的输出流

高级选择器:(和jquery相似)

querySelector() querySelectorAll() 下文中详细介绍

Element类型

元素的标签名 :nodeName 或 tagName属性

1.HTML元素

id:
title:
lang:元素内容的语言代码
dir:语言的方向
className:类名

2.取得特性

getAttribute()
setAttribute()
removeAttribute()

getAttribute("id");
getAttribute("class");

4.attributes属性

attributes属性中包含一个NamedNodeMap,与NodeList类似,也是一个动态的集合。元素的每一个特性都由一个At唐人街店表示,每个节点都保存在NameNodeMap对象中。

5.创建元素

document.createElement()方法可以创建新元素。一个参数:要创建元素的标签。

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

在使用createElement()方法创建新元素的同时,也为新元素设置了ownerDocument属性。

div.id = "myNewDiv";
div.className = "box"; 

得到的新元素尚未被添加到文档树中,要把新元素添加到文档树,可以使用appendChild()/insertBefore()/replaceChild()方法。

document.body.appendChild(div);

一旦添加到文档树中,浏览器立马呈现该元素。

6.元素的子节点

Text类型

nodeType:3 nodeName:#text nodeValue:节点所包含的文本 parentNode是一个Element 不支持子节点

nodeValue属性或data属性访问Text节点中包含的文本,这两个属性的值相同。

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为止处的字符串

div.firstChild.nodeValue = “Some other message”;

1.创建文本节点

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

var element = document.createElement("div");
element.className = "message";
var textNode = document.createTetxNode("hello world");
element.appendChild(textNode);
document.body.appendChild(element);

2.规范化文本节点

normalize()如果在一个包含两个或多个文本节点的父元素上调用normalize()方法,则会将所有的文本节点合并成一个节点。

var element = document.createElement("div");
element.className = "message";
var textNode = document.createTetxNode("hello world!");
element.appendChild(textNode);
var anothertextNode = document.createTetxNode("xunyunyun");
element.appendChild(anothertextNode);
document.body.appendChild(element);
alert(element.childNodes.length);//2
element.normalize();
alert(element.childNodes.length);//1
alert(element.firstChild.odeValue);//"hello world!xunyunyun"

浏览器永远不会创建相邻的文本节点。这种情况只会作为执行DOM操作的结果出现。

3.分割文本节点

splitText():这个方法将一个文本节点分成两个文本节点。

var element = document.createElement("div");
element.className = "message";
var textNode = document.createTetxNode("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解析技术

Comment类型

nodeType:8 nodeName:#commment nodeValue:注释内容 parentNode:可能是Document或Element 不支持(没有)子节点

与Text类型类似,除了splitText()方法之外的所有字符串操作方法。

DOM操作技术

动态脚本

var script = document.createElement("script");
script.type = "text/javascript";
script.src = "client.js";
document.body.appendChild(script);

function loadScript(url) {
	var script = document.createElement("script");
	script.type = "text/javascript";
	script.src = url;
	document.body.appendChild(script);
}
loadscript("client.js");

在兼容模式下:

function loadScriptString(code){
	var script = document.createElement("script");
	script.type = "text/javascript";
	try{
		script.appendChild(document.createTextNode(code));
	}catch(ex){
		script.text = code;
	}
	document.body.appendChild(script);
}

动态样式

var link = document.createElement("link");
link.rel = "stylesheet";
link.type = "text/css";
link.href = "style.css";
var head = document.getElementsByTagName("head")[0];
head.appendChild(link);

function loadStyles(url) {
	var link = document.createElement("link");
	link.rel = "stylesheet";
	link.type = "text/css";
	link.href = url;
	var head = document.getElementsByTagName("head")[0];
	head.appendChild(link);
}
loadStyles("style.css");

外部加载样式文件的过程时异步的,也就是加载样式与执行javascript代码的过程没有固定的次序。

var style = document.createElement("style");
style.type = "text/css";
try{
	style.appendChild(document.createTextNode("body{background-color:red}"));
	}catch(ex){
		style.styleSheet.cssText = "body{background-color:red}";
	}
}
var head = document.getElementsByTagName("head")[0];
head.appendChild(link);

操作表格

使用NodeList

NodeList、NamedNodeMap、HTMLCollection。每当文档结构发生改变时,它们都会得到更新。

DOM扩展

选择符API

1.querySelector()方法

接收一个CSS选择符,返回与该模式匹配的第一个元素,如果没有找到匹配的元素,返回null。 通过document类型调用querySelector()方法时,会在文档元素的范围内查找匹配元素。通过Element类型调用querySelector()方法时,只会在该元素后代元素的范围内查找匹配的元素。

2.querySelectorAll()方法

querySelectorAll()方法和querySelector()方法参数相同,但返回的是所有匹配的元素,为一个NodeList的实例。

3.matchesSelector()方法

接受一个参数:CSS选择符;匹配,返回true,否则,返回false。

元素遍历

属性:

childElementCount:返回子元素的个数 firstElementChild:指向第一个子元素;firstChild的元素版 lastElementChild:指向最后一个子元素;lastChild的元素版 previousElementSibling:指向前一个同辈元素;previousSibling的元素版 nextElementSibling:指向后一个同辈元素;nextSibling的元素版

HTML5

1.getELementsByClassName()方法

可以通过document对象及所有HTML元素调用该方法。

getElementsByClassName()方法接收一个参数,即包含一或多个类名的字符串,返回带有指定类的所有元素的NodeList。传入多个类名时,类名的先后顺序不重要。

使用这个方法可以更方便地为带有某些类的元素添加事件处理程序。

2.classList属性

className属性添加、删除和替换类名。因为className中是一个字符串,所以即使只修改字符串的一部分,也必须每次都设置整个字符串的值。

<div class="bd user disabled">。。。 </div>

var classNames = div.className.split(/\s+/);
var pos = -1,i,len;
for(i = 0, len = classNames.length; i < len; i++ ){
	if(classNames[i] == "user"){
		pos = i;
		break;
	}
} 
//删除类名
classNames.splice(i,1);
div.className = classNames.join(" ");

HTML5新增了一种操作类名的方式,可以让操作更加简单也更加安全,就是所有的元素添加classList属性。这个属性是新集合类型DOMTokenList的实例。方法如下:

add(value):将给定的字符串值添加到列表中。如果值已经存在,就不添加了。 contains(value):表示列表中是否存在给定的值,如果存在则返回true,否则返回false remove(value):从列表中删除给定的字符串 toggle(value):如果列表中已经存在给定的值,删除它;如果列表中没有给定的值,添加他。

上面的代码可以简化为:

div.classList.remove("user");

//迭代类名

for(var i = 0,len = div.classList.lenth; i < len; i++){ dosomething(div.classList[i]); }

支持浏览器firefox和chrome

3.焦点管理

document.activeElement属性:始终会引用DOM中当前获得了焦点的元素。

document.hasFocus()方法,用于确定文档是否获得了焦点。

4.HTMLDocument的变化

(1)readyState属性

document.readyState属性值:

loading:正在加载文档

complete:已经加载完文档

if(document.readyState == "complete"){}

(2)兼容模式

检测页面的兼容模式就是成为浏览器的必要功能。IE为此给document添加了一个名为compatmode的属性,这个属性就是为了告诉开发人员浏览器采用了哪种渲染模式。

在标准模式下document.compatMode为CSS1Compat 混杂模式下document.compatMode为BackCompat

if(document.compatMode == "CSS1Compat"){
	alert("standards mode");
}else{
	alert("Quirks mode");
}

(3)head属性

HTML5新增。引用文档的<head>元素。

var head = document.head || document.getElementByTagName("head")[0];

字符集属性

alert(document.charset);//"UTF-16"
document.charset = "UTF-8";

document.defaultCharset属性,表示浏览器默认字符集

5.自定义数据属性

HTML5规定可以为元素添加非标准的属性,但要添加前缀data-,目的是为了元素提供与渲染无关的信息,或者提供语义信息。

<div id="myDiv" data-appId="12345" data-myname="Nicholas"></div>

6.插入标记

(1)innerHTML属性

(2)outerHTML属性

(3)insetAdjacentHTML()方法

两个参数:插入位置、要插入的HTML文本

专有扩展

1.文档模式

要强制浏览器以某种模式渲染页面,可使用HTTP头部信息X-UA-Compatible。或通过等价的<meta>标签来设置:

 <meta http-equiv="X-UA-Compatible" content="IE=IEVersion">

IEVersion有以下不同的值:

Edge: EmulateIE9:

document.documentMode属性可以知道给定页面使用的什么文档模式。

2.children属性

var childCount = element.children.length;
var firstCount = element.children[0];

3.contains()方法

调用这个方法的是祖先节点,接收一个参数,即要检测的后代节点。若是,返回true;否则,返回false。

4.插入文本

(1)innerText属性

通过innerText属性可以操作元素中包含的所有文本内容,包括子文档树中的文本。他会由浅到深,将子文档数中的所有文本拼接起来。

当用它写入时,结果会删除元素的所有子节点。

(2)outerText属性

写入时,outerText就完全不同了:outerText不只替换调用它的子节点,而且会替换掉整个元素。