DOM类型
Node类型
Node接口是DOM1级就定义了,Node接口定义了12个数值常量以表示每个节点的类型值。除了IE之外,所有浏览器都可以访问这个类型。以下是常用的Node常量。
<script type="text/javascript">
//IE不支持,我们可以模拟一个类,让IE也支持。
if (typeof Node == 'undefined') {
window.Node = {
ELEMENT_NODE:1,
ATTRIBUTE_NODE:2,
TEXT_NODE:3,
COMMENT_NODE:8,
DOCUMENT_NODE:9,
DOCUMENT_TYPE_NODE:10
};
}
console.log(Node.ELEMENT_NODE);//1
console.log(Node.ATTRIBUTE_NODE);//2
console.log(Node.TEXT_NODE);//3
console.log(Node.COMMENT_NODE);//8
console.log(Node.DOCUMENT_NODE);//9
console.log(Node.DOCUMENT_TYPE_NODE);//10
</script>
Document类型
Document类型表示文档,或文档的根节点,而这个节点是隐藏的,没有具体的元素标签
//元素
document.documentElement;//html
document.body;//body
document.doctype;//<!DOCTYPE>,ie8之前会返回null
//属性
document.title;//获取和设置<title>标签的值
document.URL;//获取URL路径
document.domain;//获取域名,服务器端
document.referrer;//获取上一个URL,服务器端
//对象集合
document.anchors;//获取文档中带name属性的<a>元素集合
document.links;//获取文档中带href属性的<a>元素集合
document.applets;//获取文档中<applet>元素集合,已不用
document.forms;//获取文档中<form>元素集合
document.images;//获取文档中<img>元素集合
Text类型
Text类型用于表现文本节点类型,文本不包含HTML,或包含转义后的HTML。文本节点的nodeType为3
<script type="text/javascript">
var box = document.createElement('div');
var text = document.createTextNode('Mr.');
var text2 = document.createTextNode('Lee!');
box.appendChild(text);
box.appendChild(text2);
document.body.appendChild(box);
console.log(box.childNodes.length);
//2,在同时创建两个同一级别的文本节点的时候,会产生分离的两个节点,其实是换行了
box.normalize();//合并成一个节点,其实是把换行去掉了
box.firstChild.splitText(3);//有合并就有分离,以三个字符为距离进行换行
//除了上面的两种方法外,Text还提供了一些别的DOM操作的方法如下:
box.firstChild.deleteData(0,2); //删除从0位置的2个字符
box.firstChild.insertData(0,'Hello.');//从0位置添加指定字符
box.firstChild.replaceData(0,2,'Miss');//从0位置用Miss替换掉2个指定字符,如果第二个参数是0,则是添加Miss
box.firstChild.substringData(0,2);//从0位置获取2个字符,直接输出
console.log(box.firstChild.nodeValue);//Missllo..,输出结果
</script>
Comment类型
Comment类型表示文档中的注释。nodeType是8,nodeName是#comment,nodeValue是注释的内容。
<script type="text/javascript">
console.log(document.body.firstChild.nodeType);//8
console.log(document.body.firstChild.nodeValue);//this is comment
//在IE中,注释节点可以使用!当作元素来访问。
//var comment = document.getElementsByTagName('!');
</script>
DOM扩展
呈现模式
从IE6开始开始区分标准模式和混杂模式(怪异模式),主要是看文档的声明。IE为document对象添加了一个名为compatMode属性,这个属性可以识别IE浏览器的文档处于什么模式如果是标准模式,则返回CSS1Compat,如果是混杂模式则返回BackCompat。
<script type="text/javascript">
if (document.compatMode == 'CSS1Compat') {
console.log(document.documentElement.clientWidth);
} else {
console.log(document.body.clientWidth);
}
</script>
滚动
scrollIntoView(alignWithTop) 函数用来滚动浏览器窗口或容器元素,以便在当前视窗的可见范围看见当前元素。如果alignWithTop为true,或者省略它,窗口会尽可能滚动到自身顶部与元素顶部平齐
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<a onClick="onc()" hef="#">click here</a>
<div style="height:400px; background-color:blue"></div>
<div id="nn" style="background-color: red;height:900px;"></div>
</body>
<script type="text/javascript">
//作为一个事件的函数来被调用
function onc () {
var dd = document.getElementById("nn").scrollIntoView(true);//这个意思其实就是将这个元素滚动到浏览器窗口的顶部来显示
}
</script>
</html>
children属性
由于子节点空白问题,IE和其他浏览器解释不一致。虽然可以过滤掉,但如果只是想得到有效子节点,可以使用children属性,几乎所有浏览器都支持。
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="div">
<span>hello1</span>
<span>hello2</span>
<span>hello3</span>
</div>
</body>
<script type="text/javascript">
console.log(document.getElementById("div").children.length);//3
console.log(document.getElementById("div").children[0].innerHTML);//hello1
</script>
</html>
contains()方法
判断一个节点是不是另一个节点的后代,我们可以使用contains()方法。这个方法是IE率先使用的,开发人员无须遍历即可获取此信息
<script type="text/javascript">
var div = document.getElementById("div")
console.log(div.contains(div.firstChild));//true
</script>
早期的Firefox不支持这个方法,新版的支持了,其他浏览器也都支持,Safari2.x浏览器支持的有问题,无法使用。所以,必须做兼容
在Firefox的DOM3级实现中提供了一个替代的方法compareDocumentPosition()方法。这个方法确定两个节点之间的关系。
<script type="text/javascript">
var div = document.getElementById("div")
console.log(div.compareDocumentPosition(div.firstChild));//20
</script>
DOM操作内容
innerText属性
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="div">
<span>hello1</span>
<span>hello2</span>
<span>hello3</span>
</div>
</body>
<script type="text/javascript">
var div = document.getElementById("div")
console.log(div.innerText);//获取文本内容(如有html直接过滤掉)
div.innerText = 'Mr.Lee';//设置文本(如有html转义)
//DOM3新属性
console.log(div.textContent)
div.innerText = '<html>';
</script>
</html>
innerHTML属性
<script type="text/javascript">
document.getElementById('div').innerHTML;//获取文本(不过滤HTML)
document.getElementById('div').innerHTML = '<b>123</b>';//可解析HTML
</script>
<script type="text/javascript">
document.getElementById("div").innerHTML = "<script>alert('Lee');</script"+">";//<script>元素不能被执行
</script>
outerText属性
outerText在取值的时候和innerText一样,但是赋值方法相当危险,他不单替换了文本内容,还将元素直接抹去。
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="div">
<span>hello1</span>
<span>hello2</span>
<span>hello3</span>
</div>
</body>
<script type="text/javascript">
var div = document.getElementById("div")
console.log(div.outerText);//获取文本内容(如有html直接过滤掉)
div.outerText = 'Mr.Lee';//设置文本(如有html转义)
console.log(document.getElementById("div"));//null
</script>
</html>
outerHTML属性
outerHTML属性在取值和innerHTML一致,但和outerText也一样,很危险,赋值的之后会将元素抹去。
<script type="text/javascript">
var div = document.getElementById("div")
console.log(div.outerHTML);//获取文本内容(如有html直接过滤掉)
div.outerHTML = '<b>124</b>';//设置文本(如有html转义)
console.log(document.getElementById("div"));//null
</script>
关于最常用的innerHTML属性和节点操作方法的比较,在插入大量HTML标记时使用innerHTML的效率明显要高很多。因为在设置innerHTML时,会创建一个HTML解析器。这个解析器是浏览器级别的(C++编写),因此执行JavaScript会快的多。但,创建和销毁HTML解析器也会带来性能损失。最好控制在最合理的范围内,如下:
for (var i = 0; i < 10; i ++) {
ul.innerHTML = '<li>item</li>';//避免频繁
}
//改
for (var i = 0; i < 10; i ++) {
a = '<li>item</li>';//临时保存
}
ul.innerHTML = a;