DOM扩展
一、选择符API
主要是两个方法:目前已完全支持的浏览器有:IE8+,Firefox3.5+,Safari3.1+,Chrome,Opera10+.
1)querySelector(CSS选择符),返回与该模式匹配的第一个元素,如果没有找到返回null
var myDiv=document.querySelector('#myDiv'); //查找id
var selected=document.querySelector('.selected'); //查找class
2)querySelectorAll(css选择符),返回的是所有匹配的元素,是一个NodeList实例
能够调用querySelectorAll()方法的类型包括Document,DocumentFragment,Element
3)matchesSelector(CSS选择符),如果调用元素与该选择符匹配返回true,否则返回false。截止2011年还没有浏览器支持matchesSelector()方法。
二、元素遍历
对于元素间的空格,IE9及之前版本不会返回文本节点,而其他浏览器都会返回文本节点,这样,就导致了使用childNodes和firstChild等属性时的行为不一致。支持的浏览器有:IE9+,Firefox3.5+,Safari4+,Chrome,Opera10+.
DOM元素添加的5个属性:
1.childElementCount:返回子元素的个数(不包括文本节点和注释);
2.firstElementChild:firstChild的元素版
3.lastElementChild:lastChild的元素版
4.previousElementSibling: previousSibling的元素版
5.nextElementSibling: nextSibling的元素版
三、HTML5
1.与类相关的扩充
1)getElementsByClassName() 传入多个类名时,类名的先后顺序不重要,支持的浏览器有:IE9+,Firefox3+,Safari3.1+,Chrome,Opera9.5+.
2)classList属性,支持classList属性的浏览器只有Firefox3.6+,Chrome
add(value):将给定的字符串添加到列表中。如果值已经存在,就不添加了。
contains(value):表示列表中是否存在给定的值,如果存在则返回true,否则返回false。
remove(value):从列表中删除给定的字符串。
toggle(value):如果列表中已经存在给定的值,删除它;如果列表中没有给定的值,添加它。
//删除disabled类
div.classList.remove('disabled');
//添加current类
div.classList.add('current');
//切换user类
div.classList.toggle('user');
2.焦点管理
1)document.activeElement属性,始终会引用DOM中当前获得了焦点的元素。元素获得焦点的方式有页面加载,用户输入(通常指tab键)和在代码中调用focus()方法。默认情况下,文档刚刚加载完成时,document.activeElement中保存的是document.body元素的引用。文档加载期间,document.activeElement的值为null。
2)document.hasFocus()方法,确定文档是否获得了焦点。
支持的浏览器有:IE4+,Firefox3+,Safari4+,Chrome,Opera8+。
3.HTMLDocument的变化
1)readyState属性,有两个可能的值,loading:正在加载文档 complete:已经加载完文档
2)兼容模式 document.compatMode 标准模式下:CSS1Compat 混杂模式下:BackCompat
3) head属性
4)字符集属性
5)自定义数据属性,自定义属性以data-开头,通过dataset属性访问,eg:div.dataset.mydata //访问data-mydata属性
4.插入标记
1)innerHTML
读模式:返回与调用元素的所有子节点(包括元素、注释和文本节点)对应的HTML标记。
写模式:根据指定的值创建新的DOM树,然后用这个DOM树完全替换调用元素原先的所有子节点。
2)outerHTML
读模式:返回调用它的元素及所有子节点的HTML标签。
写模式:根据指定的HTML字符串创建新的DOM子树,然后用这个DOM子树完全替换调用元素。
3)insertAdjacentHTML(插入的位置,要插入的HTML文本)
使用innerHTML、outerHTML和insertAdjacentHTML方法时,最好先手工删除要被替换的元素的所有事件处理程序和JS对象属性。
在插入大量新HTML标记时,使用innerHTML属性与通过多次DOM操作先创建节点再指定他们之间的关系相比,效率要高得多。这是因为在设置innerHTML或outerHTML时,就会创建一个HTML解析器。这个解析器是在浏览器级别的代码基础上运行的,因此比执行JS快得多。不可避免的创建和销毁HTML解析器也会带来性能损失,所以最好能够将设置innerHTML或outerHTML的次数控制在合理的范围内。
4) scrollIntoView()
5.专有扩展
children属性
只包含元素中同样还是元素的子节点,除此之外与childNodes没有什么区别。
支持children属性的浏览器有IE5,Firefox3.5,Safari2,3,Opera8,Chrome.
6.插入文本
1)innerText
操作元素中包含的所有文本内容,包括子文档树中的文本。在通过innerText读取值时,它会按照由浅入深的顺序,将子文档树中的所有文本拼接起来。在通过innerText写入值时,结果会删除元素的所有子节点,插入包含相应文本值的文本节点。
设置innerText属性会移除先前存在的所有子节点,完全改变了DOM子树。永远只会生成当前节点的一个子文本节点,而为了确保只生成一个子文本节点,就必须要对文本进行HTML编码。
<div>
<ul>
<li>li1</li>
<li>li2</li>
<li>li3</li>
</ul>
</div>
div.innerHTML='hello & welcome,<b>"reader"</b>'; //输出hello & welcome,"ready"(粗体)
div.innerText='hello & welcome,<b>"reader"</b>'; //hello & welcome,<b>"reader"</b>
利用这一点,可以通过innerText属性过滤掉HTML标签。方法是将innerText设置为等于innerText,这样就可以去掉所有HTML标签。
div.innerText=div.innerText; //浏览器输出li1 li2 li3分行显示,但是不再是li标签,只是普通的文本。查看源代码,div中是li1<br/>li2<br/>li3<br/>
执行这行代码后,就用原来的文本内容替换了容器元素中的所有内容(包括子节点,因而也就去掉了HTML标签)。
firefox不支持innerText,提供了一个作用类似的textContent属性。为了确保跨浏览器兼容,可以向下面这样检测属性:
function getInnerText(element){
return (typeof element.textContent=='string')?element.textContent:element.innerText;
}
function setInnerText(element,text){
if(typeof element.textContent=='string'){
element.textContent=text;
}else{
element.innerText=text;
}
}
2)outerText
作用范围扩大到呢包含调用它的节点。读模式同innerText,写模式下,outerText就完全不同了,outerText不只是替换调用它的元素的子节点,而是会替换整个元素(包括子节点)。新的文本节点完全取代调用outerText的元素,此后该元素就从文档中删除,无法访问。由于这个属性导致调用它的元素不存在,因此不建议使用。