DOM的两个主要扩展:选择符API和HTML5
一.选择符API
通过CSS选择符查询DOM文档取得元素的引用(jQuery的核心)
1.querySelector()方法
接受一个CSS选择符,返回与该模式匹配的第一个元素
var myDiv=document.querySelector(“#myDiv”); //取得ID为myDiv的元素 var selected=document.querySelector(“.selected”); //取得类为selected的第一个元素 var img=document.body.querySelector(“img.button”); //取得类为button的一个图像元素 Document类型调用querySelector()方法会在文档元素的范围内查找匹配的元素。通过Element类型调用,会在该元素的子元素范围内查找
2.querySelectorAll()
返回所有匹配的元素,是一个NodeList对象,底层实现类似于一组元素的快照
var selecteds=document.querySlectetorAll(".selected"); //取得类为“selected”的所有元素 var strongs=document.querySelectorAll("p strong"); //取得p元素中所有<strong>元素
可以使用方括号语法或item()方法,访问NodeList中的每一个元素
var i,len,strong; for(i=0,len=strongs.lengeh;i<len;i++){ strong=strongs[i]; strong.className="important"; }
3.matchesSelector()方法
接受CSS选择符,如果调用的元素与该选择符匹配,返回ture
if(document.body.matchesSelector("body.page1")){ //true }
不是所有浏览器都支持此方法,但有类似的方法,所以可以编写一个函数:
function matchesSelector(element,selector){ if(element.matchesSelector){ return element.matchesSelector(selector); }else if(element,msMatchesSelector){ return element.msMatchesSelector(selector); }else if(element.mozMatchesSelector){ return element.msMatchesSelector(selector); }else if(element.webkitMatchesSeletor){ return element.webkitMatchesSeletor(selector); }else{ throw new Error("not supported"); } } if(matcheesSelctor(document.body,"body.page1")){ //执行 }
二.元素遍历
浏览器对处理元素间的空格有差异,IE9不返回文本节点,而其他浏览器返回文本节点。
Element Traversal API为DOM元素添加了5个属性:(不用担心空白文本节点)
childElementCount:返回子元素(不包含文本节点和注释)的个数
firstElementChild
lastElementChild
perviousElementSibling
nextElementSibling
跨浏览器遍历某元素的所有元素
var child=element.firstElementChild; while(child!=element.lastElmentChild){ processChild(child); child=child.nextElementSibing; }
三.HTML5
1.与类相关的扩充
用于简化CSS类的用法
(1)getElementsByClassName()
接受一个或多个类名的字符串,返回带有指定类的所有元素的NodeList
var all=document.getElementsByClsaaName("username current"); //取得类中包含“username”和“current”的元素
在document对象上调用会返回与类名匹配的所有元素,在元素上调用会返回后代元素中匹配的元素
(2)classList属性
不用classList属性修改className:
//删除一个类名 <div class="bd user disabled">...</div> var className=div.className.split(/s+/); var i,len for(i=0,len=className.length;i<len;i++){ if(className[i]=="user"){ className.split(i,1); } } div.className.join(" ");
classList属性是DOMTokenList的实例,类似于一个数组,有length属性,可以使用[]或item()
有的方法:
add(): div.add(“current”);//添加“current”类
contains(): 列表中有给定的类,返回true
remove(): 删除
toggle(): 如果存在则删除,没有则添加
2.焦点管理
元素获得焦点的方式:页面加载,用户输入,代码中调用focus()方法
(1)document.activeElement:始终指向DOM中获得了焦点的元素
var button=document.getElementById("myButton"); button.focus(); alert(document.achiveElement==button); //true
默认情况下,文档刚刚加载完成时,document.achiveElement中指向document.body,加载过程值为null
(2)document.hsaFocus()方法
用于确定文档是否获得了焦点:(知道用户是不是正在于页面交互)
var button=document.getElementById("myButton"); button.focus(); alert(document.hasFocus()); //true
3.HTMLDocment的变化
(1)readyState属性:多用于只是页面加载完成后的操作
两个可能的值:loading(正在加载文档) complete(已经加载完成文档)
if(document.readystate=="complete"){ //操作 }
(2)兼容模式
compatMode属性:告诉开发人员浏览器采用了哪种渲染模式
if(document.complete=="CSS1Compat"){ //标准模式 }else if(document.complete=="BackCompat"){ //混杂模式 }
(3)head属性
document.head //Chrome Safiri5支持 相当于:
document.getElementsByTagName(“head”)[0]
4.字符集属性
document.charset //可以访问,也可以指定
5.自定义数据属性:用于跟踪链接等
以data-开头,可以通过dataset属性访问
<div id=”myDiv” data-appId=”12345”></div>
var div=document.getElmentById(“myDiv”);
alert(div.dataset.appId);
6.插入标记
给文档插入大量新的HTML标记时,通过DOM操作非常麻烦,所以使用插入标记的技术,直接插入HTML字符串
(1)innerHTML属性
读取模式下:返回调用它的元素的子节点
写入模式下:字符串解析为DOM树,替换调用元素原来的所有子节点,要用字符转义
注意:
①通过innerHTML插入<script>元素并不会执行其中的脚本,因为<script>是“无作用域元素”,类似于注释
必须要在前边添加一个“有作用域元素”,并指定defer属性
div.innerHTML=”<input type=”hidden”><script defer>alert(“hi”);</script>"; //隐藏的input域
②<style>可以以直观的方式插入(IE8和之前的不行)
div.innerHTML=”_<style type=”text/css”>body{background-color:red;}</style>”
div.removeChild(div.firstChild); //移除前边添加的文本节点
(2)outerHTML属性
读取模式下:返回调用它的元素及所有子节点的HTML标签
写入模式下:替换调用它的节点,并插入节点
(3)insertAdjacentHTML()方法
接受插入位置:"beforebegin””afterbegin””beforeend””afterend”
要插入的HTML文本
element.insertAdjacentHTML(“beforebegin”,"<p>hello worid</p>”)
(4)内存与性能问题
在使用上述方法将元素从文档树中删除后,元素与事件处理程序之间的绑定关系在内存中并没有一并删除。导致内存数量增加,最好手动删除要被替换的元素的所有事件处理程序和JavaScript对象属性
(5)scrollIntoView()方法
可以在所有HTML元素上调用,通过滚动浏览器窗口或某个容器元素,调用元素就出现在视口中。
四.专有扩展
还没有写入标准,只得到了少数浏览器的支持
1.文档模式
强制以某种模式渲染页面:
<meta http-equiv=”X-UA-Compatible” content=”IE=EmulateIE7”> //IE7文档模式
document.documentMode :给定页面使用的是哪种文档模式
2.children属性
只包含元素的子节点(忽略了空白符),其他和childNode没什么区别
3.contains()方法:检测一个节点是不是一个节点的子节点
祖先节点调用contains,接受要检测的后代节点
alert(document.documentElement.contains(document.body)); //true 测试<body>是不是<html>元素的后代
DOM3中类似contains的方法:compareDocumentPosition()
4.插入文本
(1)innerText
读取模式:删除元素的所有节点,返回文本
写入模式:删除调用元素的所有子节点,插入相应文本值的文本节点
div.innerText=div.innerTexu; //确保只生成一个子文本节点
类似的属性: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一样
写入模式:替换调用它的元素和其子元素
5.滚动
scrollIntoViewIfNeeded()
scrollByLines():将元素内容滚动到指定行高
scrollByPages():将元素的内容滚动指定的页面高度