一,DOM变化
var supportDom2Core = document.implementation.hasFeature("Core","2.0");
var supportDOM3Core = document.implementation.hasFeature("Core","3.0");
var supportDOM2HTML = document.implementation.hasFeature("HTML","2.0");
var supportDOM2Views = document.implementation.hasFeature("Views","2.0");
var supportDOM2XML = document.implementation.hasFeature("XML","2.0");
1,针对XML命名空间的变化
HTML不支持XML的命名空间,
1)node类型中的变化
DOM2级,node类型包含下列特定于命名空间的属性
localName:不带命名空间前缀的节点名称
namespaceURI:命名空间前缀的节点名称,不存在时为null
prefix:命名空间前缀,不存在时为null
使用了命名空间前缀时,nodeName = prefix + ":" + localName
<s:svg xmlns:s="http://www.w3.org/2000/svg"></s:svg>
s为prefix,namespaceURI为http://www.w3.org/2000/svg,localName为svg
DOM3在此基础上添加了新的方法
isDefaultNamespace(namespaceURI),在指定的namespaceURI是当前节点的默认命名空间的情况下返回true
lookupNamespaceURI(prefix),返回给定的prefix的命名空间
lookupPrefix(namespaceURI),返回给定命名空间namespaceURI的前缀prefix
2)Document类型的变化
DOM2级中document类型包含下列与命名空间相关的方法
var SVG = document.createElementNS(namespaceURI,tagname),用给定的tagName元素名创建属于命名空间namespaceURI的新元素
var att = document.createAttributeNS(namespaceURI,attributeName),用给定的特性名,创建属于命名空间namespaceURI的新特性
var elems = document.getElementsByTagName(namespaceURI,tagName),返回属于namespaceURI命名空间的所有tagName元素
只有文档中包含两个文档时,这些命名空间相关的方法才必须的
3)Element类型的变化
getAttributeNS(namespaceURI,localName),取得属于namespaceURI命名空间,且名为localName的属性
getAttributeNodeNS(namespaceURI,localName),取得属于namespaceURI命名空间,名为localName的属性节点
getElementsByTagName(namespaceURI,tagName),取得命名空间,tagName元素的NodeList节点
hasAttributeNS(namespaeURI,localname),确定当前元素在当前的命名空间中是否有localName的特性
removeAttributeNS(namespaceURI,localName),移除namespaceURI命名空间的localName特性
setAttributeNS(namespaceURI,qualifiedName,value),设置命名空间namespaceURI中的名为qualifiedName的特性的值为value
setAttributeNodeNS(attribute),设置命名空间namespaceURI中的特性节点
4)NamedNode类型的变化
getNamedItemNS(namaspaceURI,localName),取得属于命名空间namespaceURI且名为localName的特性的项
removeNamedItemNS(namespaceURI,localName),移除属于命名空间namespaceURI且名为localName的特性项
setNamedItemNS(node),添加node,这个节点已经事先指定了命名信息
2,其他方面的变化
1)DocumentType的变化
新增三个属性,publicId,systemId,internalSubset
前两个表示文档声明中的两个信息段
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
document.doctype.publicId = "-//W3C//DTD HTML 4.01//EN"
document.doctype.systemId = "http://www.w3.org/TR/html4/strict.dtd"
internalSubset用于访问文档声明中额外定义
2)Document类型的变化
importNode(),从一个文档中取得一个节点,放到另一个文档中,成为另一个文档结构的一部分
接收两个参数,另一个文档中的目标节点,和一个是否复制其子节点的布尔值
var newNode = document.importNode(antherNode,true);
document.body.appendChild(newNode);
defaultView属性,指向拥有给定文档的窗口,IE中等价的属性为parentWindow
确定文档的归属窗口,var parentWindow = document.defaultView || document.parentWindow;
DOM2核心,为document.implementation对象添加了两个新方法,
createDocumentType(),用于创建新的documenType节点,接收三个参数,文档类型名称,publicId,systemId
var doctype = document.implementation.createDocumentType("html","-//W3C//DTD HTML 4.01//EN","http://www.w3.org/TR/html4/strict.dtd");
createDocument(),用于创建新的文档,接收三个参数,针对文档中元素namespaceURI,文档元素的标签名,新文档的文档类型
var doc = document.implementation.createDocument("","root",null);
DOM2级html也为document.implementation对象添加了新方法
createHTMLDocument(),用于创建一个完整的HTML文档,包括<html>,<head>,<title>,<body>元素
只接收一个参数,即创建文档的标题title元素中的字符串,返回新的html文档
var htmlloc = document.implementation.creatHTMLDocument("my doc");
3)Node类型的变化
isSupported(),用于确定当前节点拥有什么能力,接收两个参数,版本名和版本号
DOM3级引入两个辅助比较节点的方法isSameNOde(),isEqualNode(),都接收一个参数,在传人节点和引用节点相同和相等时返回true
setUserData(),将数据指定给节点,接收三个参数(设置的键,实际的数据,和处理函数)
处理函数接收5个参数,表示操作类型的值(1表示复制,2表示导入,3表示删除,4表示从命名),数据键,数据值,源节点,和目标节点
通过getUserData(),传人相同的键获取设置的值
var div = document.createElement("div"); div.setUserData("name","Nicholas",function(operation,key,value,src,dest){ if(operation == 1){ dest.setUserData(key,value,function(){}); } }); var newDIv = div.cloneNode(true); alert(newDIv.getUserData);
4)框架的变化
框架HTMLFrameElement和内联框架HTMLIFrameElement
属性contentDocument属性包含一个指针,指定表示框架内容的文档对象
IE中等价的属性为contentWindow属性
var iframe = iframe.contentDocument || iframe.contentWindow.document
二,样式
var supportsDOM2CSS = document.implementation.hasFeature("CSS","2.0");
var supportsDOM2CSS2 = document.implementation.hasFeature("CSS2","2,0");
1,访问元素的样式
css中的样式与javascript的样式名一一对应
1)DOM样式属性和方法
DOM2级样式规范给style对象定义了属性和方法
cssText:通过它能访问到style特性中的css代码
length:给定元素的css属性的数量
parentRule:css信息的cssRule对象
getPropertyCSSValue(propertyName):返回包含给定属性值的cssRule对象
getPropertyPriority(propertyName):如果给定属性使用了!improtant设置,返回"important",否则返回空字符串
getPropertyValue(propertyName):返回给定属性的字符串
item(index):返回给定位置的css属性的名称,通过length一一获取,可以使用[]方法
removeProperty(propertyName):移除给定属性
setProperty(propertyName,value,priority):将给定属性设置为相应的值,并加上优先权标志(improtant)
使用getPropertyCSSValue(propertyname),返回一个CSSValue对象,包含两个属性cssText和cssValueType
cssText属性的值与getPropertyvalue()返回值相同,属性值的字符串值,cssValueType属性是一个数值常量(0表示继承的值,1表示基本的值,2表示值列 表,3表示自定义的值)
2)计算的样式
style对象只能获取style属性的样式信息,不能获取从其他样式表折叠而来的样式信息
DOM2级增强了document.defaultView,提供了getComputedStyle()方法,接收两个参数,要取得计算样式的元素和一个伪元素字符串(如:after),不需要设 为null
返回一个CSSStyleDelaration对象,包含当前元素的所有计算的样式
var computedStyle = document.defauleView.getComputedStyle("div1",null);如此就可以获取div1元素的所有外部计算样式
IE中等价的属性currentStyle 是CSSStyleDeclaration的实例
var computedStyle = document.currentStyle;
所有的计算的样式都是只读的,不能修改计算后样式对象中的CSS属性
2,操作样式表
CSSStyleSheet类型表示样式表,
var supportsDOM2StyleSheets = document.implementation.hasFeature("StyleSheets","2.0");
CSSStyleSheet继承自StyleSheet,StyleSheet可以作为一个基础接口来定义非CSS样式表,从StyleSheet接口继承而来的属性如下
disabled:表示样式表是否被禁用的布尔值,是可读写的,可以禁用设为true
href:如果样式表通过link添加的,则值为样式表的URL,否则为null
media:当前样式支持的所有媒体类型的集合,也有一个length属性,通过item或[]获取每一项,如果集合为空,适用于所有媒体,IE中media反映link和style 标签media特殊值的字符串
ownerNode:指向拥有当前样式表的节点的指针,样式表可以通过link或style添加,如果是其他样式通过@import导入的,为null,IE不支持
parentStyleSheet:当前样式通过@import导入时,这个属性是一个指向导入它的样式表的指针
title:ownerNode中title属性的值
type:表示样式表类型的字符串,对应css样式来说,为text/css
cssRules:样式表中包含的样式规则的集合
ownerRule(index):如果样式通过@import导入,包含一个指针,指向导入的规则,否则为null,IE不支持
deleteRule(index):删除cssRules集合中指定位置的规则,IE中等价的方法removeRule()方法
insertRule(rule,index):向cssRules集合中指定的位置插入rule字符串,IE中等价的方法addRule()方法
应用与文档的所有样式表是通过document.styleSheets集合来表示的,通过length属性来获知文档中样式表的数量通过[]和item()获取每一项
直接通过link或style元素取得CSSStyleSheet对象,DOM规定了sheet属性,IE中等价的styleSheet属性
function getStyleSheet(element){return element.sheet || element.styleSheet;}
var sheet = getStyleSheet(document.getElementsByTagName("link")[0]);
1)CSS规则
CSSRule是一个供其他类型继承的基类,最常见的就是CSSStyleSheet类型,表示样式信息,包括下列属性
cssText:返回整条规则对应的文本,IE不支持,各浏览器支持情况不同
parentRule:如果当前规则是导入的规则,此属性引用导入规则,否则这个值为null
parentStyleSheet:当前规则所属的样式表,IE不支持此属性
selectorText:返回当前规则的选择符文本
style:一个CSSStyleDeclaration对象,通过它设置和获取特性的样式表
type:表示规则类型的常用类型
2)创建规则
insertRule(),添加新规则,接受两个参数,规则文本和表示插入规则的索引
sheet.insertRule("body{}",0);
IE中等价的方法addRule()
sheet.addRule("body","background-color:silver",0);
实现兼容
function insertRule(sheet,selectorText,cssText,position){ if(sheet.insertRule){ sheet.insertRule(selectorText,"{" + cssText + "}",position); }else if(sheet.addRule){ sheet.addRule(selectorText,cssText,position); } }
3)删除规则
deleteRule(),接收一个参数,要删除的规划的位置 IE中等价的方法,removeRule(),使用方法相同 function deleteRule(sheet,index){ if(sheet.deleteRule){ sheet.deleteRule(index); }else if(sheet.removeRule){ sheet.removeRule(index); } }
3,元素大小
1)偏移量
offsetHeight:元素在垂直方向上占用的空间大小,包括元素的高度,水平滚动条的高度,上下边框的高度
offsetWidth:元素在水平方向上占用的空间大小,包括元素的宽度,垂直滚动条的宽度,左右边框的高度
offsetLeft:元素左外边框至包含元素的左内边框之间的像素距离
offsetTop:元素上外边框至包含元素的上内边框之间的像素距离
offsetParent:包含元素的引用
function getElementLeft(element){ var actualLeft = element.offsetLeft; var current = element.offsetParent; while(current != null){ actualLeft += current.offsetLeft; current = current.offsetParent; } return actualLeft; } function getElementTop(element){ var actualTop = element.offsetTop; var current = element.offsetParent; while(current != null){ actualTop += current.offsetTop; current = current.offsetParent; } return actualTop; }
2)客户区大小
是指元素内容及其内边距所占据的空间大小
clientWidth:元素内容的宽度和左右内边距宽度
clientHeight:元素内容的高度和上下内边距宽度
确定浏览器视口的大小
function getViewport(){ if(document.compatMode == "BackCompat"){ return { document.body.clientWidth; height:document.body.clienHeight; }; }else{ return{ document.documentElement.clientWidth; height:document.documentELement.clientHeight; }; } }
3)滚动大小
包含滚动内容的元素的大小,四个相关的特性
scrollHeight:在没有滚动的情况下,元素内容的总高度
scrollWidth:在没有滚动的情况下,元素内容的总宽度
scrollLeft:被隐藏在内容区域左侧的像素数,通过设置这个属性可以改变元素的滚动位置
scrollTop:被隐藏在内容区域上方的像素数,通过设置这个属性可以改变元素的滚动位置
混杂模式下的IE,要document.body代替document.documentElement
将scrollLeft和scrollTop设置为0,可以重置滚动位置
function scrollTOTOP(element){ if(element.scrollTop != 0){ element.scrollTop = 0; } }
4)确定元素大小
每个元素都提供了getBoundingClientRect()方法,返回一个矩形对象有四个属性,left top right bottom,给出了元素在页面中相对于视口的位置
function getBoundingClientRect(element){ var scrollTop = document.documentElement.scrollTop; var scrollleft = document.documentElement.scrollLeft; if(element.getBoundingClientRect){ if(typeof argument.callee.offset != 'number'){ var temp = document.createElement("div"); temp.style.cssText = "position:absolute;left:0;top:0"; document.body.appendChild(temp); argument.callee.offset = -temp.getBoundingClientRect().top - scrollTop; document.body.removeChild(temp); temp = null; } var rect = element.getBoundingClientRect(); var offset = argument.callee.offset; return{ left:rect.left + offset; right:rect.right + offset; top:rect.top + offset; bottom:rect.bottom + offset; }; }else{ var actualLeft = getElementLeft(element); var actualTop = getElementTop(element); return{ left:actualLeft - scrollLeft; right:actualLeft + element.offsetWidth -scrollLeft; top:actualTop - scrollTop; bottom:actualTop + element.offsetHeight - scrollTop; }; } }
三,遍历
var supportsTraversals = document.implementation.hasFeature("Traversal","2.0");
var supportsNodeIterator = (typeof document.createNodeIterator == 'function');
var supportsTreeWalker = (typeof document.createTreeWalker == 'function');
1,NodeIterator
1)document.createNodeIterator()方法创建它的新实例,接收四个参数
root:作为搜索起点的树中的节点
whatToShow:表示要访问哪些节点的数字代码
filter:是个NodeFilter对象,是否接受某种特定节点的函数
entityReferenceExpansion:布尔值,表示是否要扩展实体引用
2)whatToShow是一个位掩码,以常量形式在NodeFilter类型中定义
NodeFilter.SHOW_ALL:显示所有节点
NodeFilter.SHOW_ELEMENT:显示元素节点
NodeFilter.SHOW_ATTRIBUTE:显示属性节点
NodeFilter.SHOW_TEXT:显示文本节点
NodeFilter.SHOW_CDATA_SECTION:显示CDATA节点
NodeFilter.SHOW_ENTITY_REFERENCE:显示实体引用节点
NodeFilter.SHOW_ENTITY:显示实体节点
NodeFilter.SHOW_PROCESSING_INSTRUCTION:显示处理指令节点
NodeFilter.SHOW_COMMENT:显示注释节点
NodeFilter.SHOW_DOCUMENT:显示文档节点
NodeFilter.SHOW_DOCUMENT_TYPE:显示文档类型节点
NodeFilter.SHOW_DOCUMENT_FRAMENT:显示文档片段节点
NodeFilter.SHOW_NOTATION:显示符号节点
3)通过createNodeIterator()方法的filter参数来自定义NodeFilter对象,只有一个acceptNode()方法
应该访问给定的节点,返回NodeFilter_FILTER_ACCEPT,否则返回NodeFilter_FILTER_SKIP
NodeFilter是一个抽象的类型,不能直接创建它的实例,只要创建一个包含acceptNode()方法的对象,将这个对象传给createNodeIterator()即可
var filter = { acceptNode:function(node){ return node.tagName.toLowerCase() == "p"?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIT; } };
var iterator = document.createNodeiterator(root,NodeFilter.SHOW_ELEMENT,filter,false);
第三个参数可以与acceptNode函数相同
var filter = function(node){ return node.tagName.toLowerCase() == "p"?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIT; }; var iterator = document.createNodeiterator(root,NodeFilter.SHOW_ELEMENT,filter,false); var iterator = document.createNodeiterator(root,NodeFilter.SHOW_ELEMENT,null,false);可以访问所有类型节点
4)nextNode() 和 previousNode()方法,返回div中所有li元素
var div = document.getElementById("div"); var filter = function(node){ return node.tagName.toLowerCase() == "li"?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP; }; var iterator = document.createNodeIterator(div,NodeFilter.SHOW_ELEMNT,filter,false); var node = iterator.nextNode(); while(node != null){ alert(node.tagName); node = iterator.nextNode(); }
2,TreeWalker
1)不同方向上遍历DOM结构的方法
parentNode():遍历当前节点的父节点
firstChild():遍历到当前节点的第一个子节点
lastChild():遍历到当前节点的最后一个子节点
nextSibiling():遍历到当前节点的下一个节点
previousSibiling():遍历到当前节点的上一个子节点
2)创建TreeWalker对象要使用document.createTreeWalker()方法,参数同上
fitler对象返回值不同,还有NodeFilter_FILTER_REJECT,会跳过相应节点和该节点的子树
3)不定义过滤器
var div = document.getElementById("div"); var walker = createTreeWalker(div,NodeFilter.SHOW_ELEMENT,null,false); walker.firstChild(); walker.newSibiling(); var node = walker,firstChild(); while(node != null){ alert(node.tagName); node.nextSibiling(); }
4)currentNode属性,表示任何遍历方法在上一次遍历中返回的节点
四,范围
1,DOM中的范围
document类型中定义了createRange()方法
var supportsRange = document.implementation.hadFeature("Range","2.0");
var alsoSupportsRange = (typeof document.createRange == 'function');
var range = document.createRange();创建的实例提供了属性和方法如下
startContainer:包含起点的节点(即第一个子节点的父节点)
startOffset:范围在startContainer中起点的偏移量,第一个子节点的索引值
endContainer:包含终点的节点
endOffset:范围在endContainer中终点的偏移量,最后一个子节点的索引值
commonAncestorContainer:startContainer和endContainer共同祖先节点在文档树中位置最深的一个
1)用DOM范围实现简单的选择
selectNode():接收一个DOM节点参数,选择整个节点包括子节点
selectNodeContents():接收一个DOM节点参数,只选择节点的子节点
var range1 = document.createRange(); var range2 = document.createRange(); var p1 = document.getElementsByTagName("p")[0]; range1.selectNode(p1); range2.selectNodeContents(p1);
setStartBefore(refNode):将范围的起点设置在refNode之前,refNode是范围选区的第一个子节点,startContainer=refNode.parentNode
setStartAfter(refNode):将范围的起设置在refNode之后,refNode的下一个同辈节点为范围的起点,startContainer=refNode.parentNode;
setEndBefore(refNode):将范围的终点设置在refNode之前,refNode的前一个同辈节点为范围的终点,endContainer=refNode.parentNode
setEndAfter(refNode):将范围的终点设置在热饭Node之后,refNode是范围选区的最后一个子节点,endContainer=refNode.parentNode
2)用DOM范围实现复杂的选择
使用setStar(参照节点startContainer,偏移量startOffset)
使用setEnd(参照节点endContainer,偏移量endOffset)
var range1 = document.createRange(); var range2 = document.createRange(); var p1 = document.getElementById("p1"); var p1index = -1;var i;var len; for(i=0,len=p1.parentNode.childNodes.length;i<len;i++){ if(p1.parentNode.childNode[i] == p1){ p1index = i; break; } } range1.setStart(p1.parentNode,p1index); range1.setEnd(p1.parentNode,p1index+1); range2.setStart(p1,0); range2.seEnd(p1,p1.childNodes.length);
3)操作DOM范围中的内容
创建的范围,内部为这个范围创建一个文档片段
第一个办法使用deleteContents()方法,从文档中删除选区包含的内容
<p id="p1"><b>hello</b> world</p>
var p1 = document.getElementById("p1");
var hello = p1.firstChild.firstChild;
var world = p1.lastChild;
var range = document.createRange();
range.setStart(hello,2);
range.setEnd(world,3);
range.deleteContents();
页面显示代码如下<p><b>he</b>rld!</p>
第二个方法extractContents(),会返回范围的文档片段,利用这个值将范围片段插入到文档中
<p id="p1"><b>hello</b> world</p>
var p1 = document.getElementById("p1");
var hello = p1.firstChild.firstChild;
var world = p1.lastChild;
var range = document.createRange();
range.setStart(hello,2);
range.setEnd(world,3);
var fragment = range.extractContents();
p1.parentNode.appendChild(fragment);
页面显示<p><b>he</b>rld!</p>
<b>llo</b> wo
第三个方法使用cloneContents()创建范围对象的副本,在文档其他地方插入
<p id="p1"><b>hello</b> world</p>
var p1 = document.getElementById("p1");
var hello = p1.firstChild.firstChild;
var world = p1.lastChild;
var range = document.createRange();
range.setStart(hello,2);
range.setEnd(world,3);
var fragment = range.cloneContents();
p1.parentNode.appendChild(fragment);
页面显示<p><b>hello</b>world</p>
<b>llo</b> wo
4)插入DOM范围中的内容
insertNode(),可以向范围选区的开始插入一个节点
surroundContents(),环绕范围插入内容,接收一个参数,环绕范围内容的节点
5)折叠DOM范围
使用折叠范围时,位置会落在完档中两个部分之间,可能是选区开始,或结束
collapse(),接收一个参数,布尔值,表示折叠到那一端,true表示到起点,false表示到终点
通过检查collapse属性,判断是否完成折叠,通过是否处于折叠状态,判断范围中的两个节点是否紧密相邻
6)比较DOM范围
compareBoundarypoints()方法,确定多个范围时是否有公共的边界,接收两个参数,表示方式的常量值,比较的范围
常量值如下
Range_START_TO_START(0) :第一个范围和第二个范围的起点
Range_START_TO_END(1):第一个范围的起点和第二个范围的终点
Range_END_TO_END(2):第一个范围和第二个范围的终点
Range_END_TO_START(3):第一个范围的终点和第二个范围的起点
返回值为-1(前在后之前,正常顺序)0(前后相等)1(前在后之后,逆序)
7)复制DOM范围
var newRange = range.cloneRange();
8)清理DOM范围
range.detach();
range = null;
2,IE8及更早版本中的范围
IE只支持文本范围,var range = document.body.createTextRange();
1)用IE范围实现简单的选择
findText(),找到第一次出现的给定的文本,并将范围移过来环绕该文本,没有返回false
var found = range.findText("text");传人第二个参数表示方向,1为向前搜索,-1为向后搜索
moveToElementText(),接收一个DOM元素,选择该元素的所有文本
htmlText属性取得范围的全部范围
parentElement()与DOM中commonAncestorContainer()等价
2)使用IE范围实现发杂的选择
以特定的增量向四周移动范围,move(),moveStart(),moveEnd(),expand(),接收两个参数,移动单位和移动数量
character:逐个字符,word:逐个单词,sentent:逐个句子,textedit:移动到当前范围选区开始或结束位置
moveStart是移动范围起点,moveEnd是移动范围终点,expand(),将范围规范化,将选择部分文本的部分全部选中
move会首先折叠当前范围,调用之后要使用movestar,moveEnd创建新的额选区
3)操作IE范围中的内容
text属性,range.text = ''
pasteHTML()方法 range.paeteHTML("<em></em>")
4)折叠IE范围
collapse(),参数true折叠到起点,false折叠到终点
collapse不能用来判断是否发生折叠
boundingWidth属性,如果为0证明发生折叠
5)比较IE范围
compareEndPoints()方法,用法同compareBoundaryPoints(),接收两个参数,比较类型和比较范围
比较类型的取值范围:StartToStart,StartToEnd,EndToEnd,EndToStart
返回值,第一个范围的边界位于第二个范围的边前面返回-1,相等返回0,否则返回1
isEqual(),用于确定两个范围是否相等
isRange(),用于判断一个范围是否包含另一个范围,调用者包含参数返回true
6)复制IE范围
var newRange = range.duplicate();