DOM扩展
对DOM的两个主要的扩展是Selectors API(选择符API)和 HTML5。
(一)选择符API
Selectors API Level 1 的核心是两个方法:querySelector() 和querySelectorAll() 。
在兼容的浏览器中,可以通过 Document 及Element类型的实例调用它们。目前已完全支持 Selectors API Level 1的浏览器有 IE 8+、Firefox 3.5+ 、Safari 3.1+、Chrome和Opera 10+。
1.querySelector() 接收一个CSS选择符,返回与该模式匹配的第一个元素,没有则返回null。
Document类型调用时会在文档元素范围内查找,Element类型调用时只会在该元素后代元素范围内查找
//取得body元素 var body = document.querySelector("body"); //取得ID为myDiv的元素 var myDiv = document.querySelector("#myDiv"); //取得类为selected的第一个元素 var selected = document.querySelector(".selected"); //取得类为botton的第一个图像元素 var img = document.body.querySelector("img.button");
2.querySelectorAll() 返回的是所以匹配的元素,返回的是一个NodeList的实例。
要得到每一个返回的元素,可以使用item()方法或方括号语法。
3.matchesSelector() 接收一个CSS选择符,如果调用元素与该选择符匹配,则返回true,否则返回false。
在取得某个元素引用时,使用这个方法能方便检测它是否会被querySelector()和querySelectorAll()方法返回。
最后编一个包装函数来用这个方法。
function matchesSelector(element, selector){ if (element.matchesSelector){ return element.matchesSelector(selector); } else if (element.msMatchesSelector){//IE9+ return element.msMatchesSelector(selector); } else if (element.mozMatchesSelector){//Firefox3.6+ return element.mozMatchesSelector(selector); } else if (element.webkitMatchesSelector){ return element.webkitMatchesSelector(selector); } else { throw new Error("Not supported."); } }
(二)元素遍历
Element Traversal API
childElementCount:返回子元素节点个数
firstElementChild:指向第一个子元素
lastElementChild:指向最后一个子元素
previousElementSibling:指向前一个同辈元素
nextElementSibling:指向后一个同辈元素
IE9+ Firefox 3.5+ Sarafi 4+ Chrome 和Opera10+
(三)HTML5
1.与类相关的扩充
①getElementsByClassName() :接收一个参数,包含一个或多个类的字符串,返回带有指定类的所有元素的NodeList。
在document对象调用返回与类名相同的所有元素,在元素上调用只返回后代元素里匹配的元素,但返回的是NodeList对象,与使用getElementByTagName()和其他返回NodeList的DOM方法都有同样的问题。
IE9+ Firefox 3+ Sarafi 3.1+ Chrome 和Opera 9.5+
2.classList属性
//删除"user"类 //取得类名字符串并拆分成数组 var className = div.className.split(/\s+/); //找到要删的类名 var pos = -1, //没找到就返回-1,即不删除 i, len; for (i=0, len=classNames.length; i < len; i++) { if (classNames[i] == "user") pos = i; break; } //删除类名 className.splice(i,1); //把剩下的类名拼成字符串并重新设置 div.className = className.join(" ");
classList属性是新集合类型DOMTokenList的实例。
方法:add(value) :添加
contains(value):是否存在给定值
remove(value):删除
toggle(value):如果存在给定值就删除,没有则添加
IE10+ Firefox 3.6+ Chrome
2.焦点管理
document.activeElement属性 始终引用DOM当前获得了焦点的元素。
document.hasFocus()方法 :确定文档是否获得焦点。
元素获得焦点的方法有页面加载、用户输入(通常是通过按Tab键)和在代码调用focus()方法。
文档加载完成时document.activeElement保存的是document.body元素,在加载期间为null。
IE 4+ Firefox 3+、Safari 4+、Chrome和Opera 8+。
3.HTMLDocument的变化
①readyState属性
有两个值:loading正在加载文档 complete已经加载完文档
用来实现一个指示文档已经加载完成的指示器。
②兼容模式
compatMode 属性 告诉开发人员浏览器用了哪种渲染模式 标准模式document.compatMode的值为"CSS1Compat",混杂模式下为"BackCompat"。
③head属性
var head = document.head||document.getElementByTagName("head")[0];
4.字符集属性
charset属性 文档中实际使用的字符集,默认为"UTF-16"。
defaultCharset属性 根据默认浏览器及操作系统的设置,当前文档默认的字符集应该是什么。
5.自定义数据属性
HTML5规定非标准的属性要添加前缀data-,目的是为元素提供与渲染无关的信息,或提供语义信息。
dataset属性访问自定义属性的值,每个data-name形式的属性都会有一个对象的属性,只不过属性名没有前缀。
IE11 FIrefox 6+ Chrome
6.插入标记
①innerHTML属性
在读模式下返回调用模式的所有子节点的HTML标记。
在写模式下创建新的DOM树并将它完全替换调用元素原先的所有子节点。
不同浏览器返回的文本格式不同,IE低版本、Opera所有标签大写。
在写模式下如果值包含HTML标签会根据浏览器转换为元素。
document.getElementById("hehe").innerHTML="Hello & welcome,<b>\"reader\"!</b>"; alert(document.getElementById("hehe").innerHTML);
大多数浏览器innerHTML插入<script>不会执行脚本,只有IE8及之前版本可以,但需要为<script>指定defer属性,并让<script>元素位于“有作用域的元素”后。
div.innerHTML = "<input type=\"hidden\"><script deffer>alert(‘hi‘);</script>";
大多数浏览器支持这样插入<style>元素到innerHTML,但IE8和之前的版本也有上面的问题。
div.innerHTML = "<style type=\"text/css\">body {background-color: red;}</script>"
不支持innerHTML的元素有<col> <colgroup> <frameset> <head> <html> <style> <table> <tbody> <thead> <tfoot> <tr>,IE8及更早版本不支持<title>。
②outerHTML属性
在读模式下返回调用它的元素及所有子节点的HTML标签。
在写模式下根据指定的HTM字符串创建新的DOM子树并用它完全替换调用元素。
Firefox 7 及之前版本都不支持outerHTML。
③insertAdjacentHTML()方法
接收两个参数:插入位置和插入的HTML文本,第一个参数必须是这些值之一:beforebegin afterbegin beforeend afterend。
IE Firefox 8+ Sarafi Opera Chrome
④内存与性能问题
//每次循环都要设置一次innerHTML,还要从innerHTML读取一次数据 for (var i=0,len=values.length;i<len;i++){ ul.innerHTML += "<li>" + value[i] + "</li> "; } //单独构建字符串, var itemHTML = ""; for (var i=0,len=values.length;i<len;i++){ itemsHTML += "<li>" + value[i] + "</li> "; } ul.innerHTML = itemsHTML;
7.scollIntoview()方法
通过滚动浏览器窗口或某个容器元素,调用元素就可以出现在视口中。如果传入true或不传入参数,窗口滚动之后会让调用元素的顶部与视口顶部尽可能平齐。传入false调用元素会尽可能全部出现在视口。
(四)专有扩展
1.文档模式
documentMode
2.children属性
只包含元素中同样还是元素的子节点,与childNodes没什么区别。
IE5 Firefox 3.5 Safari 3 Opera8,IE9之后只返回元素节点
3.containss()方法
调用的元素是祖先节点,接收一个参数:后代节点。如果被检测的节点是后代节点,则返回true。
IE Firefox 9+ Sarafi Opera Chrome
//通用的containers函数 function contains(refNode, otherNode){ if (typeof refNode.contains == "function" && (!client.engine.webkit || client.engine.webkit >= 522)){ return refNode.contains(otherNode); } else if (typeof refNode.compareDocumentPosition == "function"){ return !!(refNode.compareDocumentPosition(otherNode) & 16); } else { var node = otherNode.parentNode; do { if (node === refNode){ return true; } else { node = node.parentNode; } } while (node !== null); return false; } }
4.插入文本
①innerText属性
读取值时会安装由浅入深的顺序将子文档树的所有文本拼接。
写入值时会删除所有子节点,插入包含相应文本值的文本节点、
将innerText设置为等于InnerText可以去掉所有HTML标签。
IE4+ Sarafi3+ Opera 8+ Chrome
innerText会忽略行内的样式和脚本,textContent像返回其他文本一样返回行内的样式和脚本代码。
②outerText属性
5.滚动
scollIntoViewIfNeeded
scollByLines
ScollBypages