DOM进阶:DOM拓展和DOM操作内容
DOM扩展
1.呈现模式:从IE6开始开始区分标准模式和混杂模式(怪异模式),主要是看文档的声明。
IE为document对象添加了一个名为compatMode属性,这个属性可以识别IE浏览器的文档处于什么模式如果是标准模式,则返回CSS1Compat,如果是混杂模式则返回BackCompat。
PS:后来Firefox、Opera和Chrome都实现了这个属性。从IE8后,又引入documentMode新属性(该属性的值有三个数值),因为IE8有3种呈现模式分别为标准模式8,仿真模式7,混杂模式5。
2.滚动:DOM提供了一些滚动页面的方法,如下:
document.getElementById('box').scrollIntoView(); //设置指定可见
scrollIntoView()可以在所有的HTML元素上调用,通过滚动浏览器窗口或某个容器元素,调用元素就可以出现在视窗中。如果给该方法传入true作为参数,或者不传入任何参数,那么窗口滚动之后会让调动元素顶部和视窗顶部尽可能齐平。如果传入false作为参数,可能的话,调用元素的底部会与视口的顶部齐平)。
3.children属性:由于子节点空白问题,IE和其他浏览器解释不一致。虽然可以过滤掉,但如果只是想得到有效子节点,可以使用children属性,支持的浏览器为:IE5+、Firefox3.5+、Safari2+、Opera8+和Chrome,这个属性是非标准的。
var box = document.getElementById('box');
alert(box.children.length); //得到有效子节点数目
4.contains()方法
判断一个节点是不是另一个节点的后代,我们可以使用contains()方法。这个方法是IE率先使用的,开发人员无须遍历即可获取此信息。
var box = document.getElementById('box');
alert(box.contains(box.firstChild)); //true
早期的Firefox不支持这个方法,新版的支持了,其他浏览器也都支持,Safari2.x浏览器支持的有问题,无法使用。所以,必须做兼容。
在Firefox的DOM3级实现中提供了一个替代的方法compareDocumentPosition()方法。这个方法确定两个节点之间的关系。
var box = document.getElementById('box');
alert(box.compareDocumentPosition(box.firstChild)); //20
关系掩码表
掩码 节点关系
1 无关(节点不存在)
2 居前(节点在参考点之前)
4 居后(节点在参考点之后)
8 包含(节点是参考点的祖先)
16 被包含(节点是参考点的后代)
为什么会出现20,那是因为满足了4和16两项,最后相加了。
DOM操作内容
虽然在之前我们已经学习了各种DOM操作的方法,这里所介绍是innerText、textContent、innerHTML、outerText和outerHTML等属性。
1.innerText属性
document.getElementById('box').innerText; //获取文本内容(如有html直接过滤掉)
document.getElementById('box').innerText = 'Mr.Lee'; //设置文本(如有html转义)
2.textContent属性
原本在firefox中没有innerText,只有一个替代属性textContent
后来firefox也实现了innerText,其他浏览器也实现了textContent
两者的区别
textContent或获取style和script中的文本内容,而innerText会忽略
textContent依赖于代码,如获取display:none的元素的文本,而innerText依赖页面显示
textContent设置的时候不一定会触发“回流”,而innerText一定触发“回流”
回流就是DOM树从根节点重新渲染,重绘是只回执DOM树中的部分节点
textContent返回值不会被格式化,innerText会被格式化
innerText会把空标签当作换行(连续多个空标签算一个换行),textContent只返回一行文本(有子标签才会返回多行文本)
3.innerHTML属性:这个属性不拒绝HTML。
document.getElementById('box').innerHTML; //获取文本(不过滤HTML)
document.getElementById('box').innerHTML = '<b>123</b>'; //可解析HTML
虽然innerHTML可以插入HTML,但本身还是有一定的限制,也就是所谓的作用域元素,离开这个作用域就无效了。
box.innerHTML = "<script>alert('Lee');</script>"; //script元素不能被执行
box.innerHTML = "<style>background:red;</style>"; //style元素不能被执行
4.outerText
outerText在取值的时候和innerText一样,同时火狐不支持,而赋值方法相当危险,他不单替换了文本内容,还将元素直接抹去。
var box = document.getElementById('box');
box.outerText = '<b>123</b>';
alert(document.getElementById('box')); //null,建议不去使用
5.outerHTML
outerHTML属性在取值和innerHTML一致,但和outerText也一样,很危险,赋值的之后会将元素抹去。
var box = document.getElementById('box');
box.outerHTML = '123';
alert(document.getElementById('box')); //null,建议不去使用,火狐旧版未抹去
PS:关于最常用的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;