12 DOM2和DOM3
12.1 DOM变化
12.1.1 针对XML命名空间的变化(了解即可)
增加了XML命名空间,不同XML文档的元素可以混合在一起,共同构成格式良好的文档,而不必担心发生命名冲突.
Node类型的变化
在DOM2中,Node类型包含下列特定于命名空间的属性.
- localName:不带命名空间前缀的节点名称
- namespaceURI:命名空间URI或者null
- prefix:命名空间前缀或者null
DOM3在此基础上更进一步,引入了下列与命名空间有关的方法
- isDefaultNamespace:在指定的namespaceURI是当前节点的默认命名空间的情况下返回true
- lookupNamespaceURI:返回给定prefix的命名空间
- lookupPrefix:返回给定namespaceURI的前缀
Document类型变化
DOM2级中的Document类型也发生了变化
- createElementNS:使用给定的tagname创建一个属于命名空间namespaceURI的新元素
- createAttributeNS:使用给定的attributeName创建一个属于命名空间namespaceURI的新特性
- getElementsByTagNameNS:返回属于命名空间namespaceURI的tagName元素的NodeList
Element类型变化
DOM2级核心中有关Elementde变化
- getAttributeNS:取得属于命名空间namespaceURI且名为localname
- getAttributeNodeNS:取得属于命名空间namespaceURI,且名为localName的特性节点
- getElementsByTagNameNS:返回属于命名空间namespaceURI的tagName元素的Nodelist
- hasAttributesNS:确定当前元素是否一个名为localName.
- removeAttributesNS:删除属于命名空间namespaceURI且名为localName
- setAttributesNS:设置属于命名空间namespaceURI.
- setAttributesNodeNS设置属于命名空间namespaceURI的特性节点
NameNodeMap类型变化
- getNamedItemNS:取得属于命名空间namespaceURI且名为localName
- removeNamedItemNS:移除属于命名空间namespaceURI且名为localName
- setNamedItemNS:添加node,这个节点已经事先制定了命名空间信息
12.1.2 其他方面的变化
DocumentType
新增了3个属性:publicId,systemId,internalSubset
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body></body>
</html>
<script>
console.log(document.doctype.publicId); //-//W3C//DTD HTML 4.01//EN
console.log(document.doctype.systemId); //http://www.w3.org/TR/html4/strict.dtd
console.log(document.doctype.internalSubset); //验证了一下好像不能实现
</script>
Document类型的变化
1.importNode
从一个文档获取一个节点,然后将其导入另一个文档,使其成为这个文档结构的一部分
HTML中不常用,在XML文档中常用
2.defaultView
DOM2级视图添加的,其中保存一个指针,指向拥有给定文档的窗口.IE提供的是parentWindow
console.log(document.defaultView);
3.document.implementation新增方法
- createDocumentType
创建一个新的的DocumentType节点,接受3个参数:文档类型名称,publicId,systemId,只有创建新文档时才有用
var doctype = document.implementation.createDocumentType("html", "", "");
console.log(doctype);//<!DOCTYPE html >
- createDocument
创建一个Document类型
var doc = document.implementation.createDocument("", "root", null);
console.log(doc);//#document
- createHTMLDocument
创建完整的的HTML文档
var html = document.implementation.createHTMLDocument("new doc");
console.log(html); //#document
node类型的变化
DOM2增加:isSupport方法与DOM1的hasFeature类似,用于确定当前节点具有什么能力
DOM3增加:isSameNode和isEqualNode,都接受有一个参数,并在传入节点与引用节点相同或相等时返回true,判断连个节点是否是一个对象
DOM3增加:setUserData方法和getUserData方法,添加数据方法
框架的变化
contentDocument
包含一个指针,指向表示框架内容的文档对象
var iframe = document.getElementById("myIframe");
var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
console.log(iframeDoc);
12.2 样式
定义样式的方式3种方式:
- 通过link元素引入外部样式表
- 使用style元素定义嵌入式样式
- 使用内联style属性对特定元素设置样式
验证css能力:
var supportDOM2CSS = document.implementation.hasFeature("CSS", "2.0");
console.log(supportDOM2CSS);
var supportDOM2CSS2 = document.implementation.hasFeature("CSS2", "2.0");
console.log(supportDOM2CSS2);
12.2.1 访问元素的样式
元素的style对象
CSSStyleDeclaration的实例;
- 只包含使用内联style属性对特定元素设置样式,不包含外部样式表和嵌入样式表
- 对于使用短划线的css属性名,必须将其转化成驼峰大小写形式,才能通过js来访问
css属性 | js属性 |
---|---|
background-image | backgroundImage |
color | color |
display | display |
font-family | fontFamily |
1.DOM样式属性和方法
DOM2级样式规范还为style对象定义了一些属性和方法.
- cssText:能够访问到style特性中的css代码
- length:应用给元素的CSS属性的数量
- parentRule:表示CSS信息的CSSRlue对象.
- getPropertyPriority():如果给定的属性使用了!important设置,则返回"important";否则返回空字符串;
- getPropertyCSSValue():返回包含给定属性值的CSSValue对象
- getPropertyValue():返回给定属性的字符串值
- item(index):返回给定位置的CSS属性的名称
- removeProperty():从样式中删除给定属性
- setProperty(propertyName,value,priority):将给定属性设置为相应的值,并加上优先权标志
2.计算的样式
getComputedStyle()方法
- DOM2级样式增强了document.defaultview,提供了getComputedStyle()方法.
- 接收两个参数,要去的计算样式的元素和一个伪元素字符串
//内嵌样式表
#demo {
width: 50px;
height: 50px;
background-color: royalblue;
}
//dom节点.包括内联style样式表
<div id="demo" style="border: 1px solid red; width: 100px"></div>
//使用getComputedStyle回去计算后的样式
var demo = document.getElementById("demo");
var computedStyle = document.defaultView.getComputedStyle(demo, null);
console.log(computedStyle.width);//计算后的宽度
IE不支持这个方法,使用currentstyle可以替代
12.2.2 操作样式表
- CSSStyleSheet类型表示的是样式表,包括通过link元素引入的外部样式表和style元素内嵌样式表.
- link元素引入的外部样式表是用HTMLLinkElement类型表示
- style元素内嵌样式表是用HtMLStyleElement类型表示
CSSStyleSheet继承自StyleSheet,后者可以作为一个基础接口来定义非CSS样式表.从StyleSheet接口继承而来的属性如下:
- disabled:表示样式表是否被禁用的布尔值.
- href:如果样式表示通过link元素包含的,则是样式表的URL;否则,是null;
- media:当前样式表支持的所有媒体类型的集合.
- ownerNode:指向拥有当前样式表的节点的指针,样式表可能是在HTMl中通过link或style引入的.
- parentStyleSheet:在当前样式表是通过@import导入情况下,这个属性是一个指向导入它的样式表指针
- title:ownerNode中title属性值
- type:表示样式表类型字符串.
- cssRule:样式表中包含的样式规则的集合.
- ownerRule:如果样式表是通过@import导入的,这个属性就是一个指针,只想表示导入的规则.
- deleteRule:删除cssRule集合中指定位置的规则.
- insertRule:向cssRules集合中指定的位置插入rule字符串.IE不支持这个方法,但支持一个类似的addRule()方法;
通过document.styleSheets集合来表示文档中所有的样式表.通过这个集合的lenght属性可以获知文档中样式表的数量
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="./css.css" />
</head>
<style>
.div {
width: 100px;
height: 100px;
background-color: tomato;
z-index: 1000;
}
</style>
<style>
.demo {
width: 100px;
height: 100px;
background-color: tomato;
z-index: 1000;
}
</style>
<body>
<div class="div"></div>
<div class="demo"></div>
</body>
</html>
<script>
var div = document.getElementById("div");
console.log(document.styleSheets);
</script>
效果:
1.css规则
CSSRule对象表示样式表中每一条规则.实际上,CSSRule是一个提供其他多种类型继承的基类型,其中最常见的就是CSSStyleRule类型,表示样式信息(其他规则还有@import,@font-face,@page和@charset)
- cssText:返回整条规则对应的文本.
- parentRule:如果当前规则是导入规则,这个属性引用的就是导入规则;
- parentStyleSheet:当前规则所属的样式表;
- selectorText:返回当前规则的选择符文本.
- style:一个CSSStyleDeclaration对象,可以通过它设置和取得规则中特定的样式值
- type:表示规则类型的常量值.
常用的是cssText,selectorText和style;
2.创建规则
insertRule()方法,IE中使用addRule()方法;
接受两个参数:规则文本和插入规则的索引;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="./css.css" />
</head>
<style>
.div {
width: 100px;
height: 100px;
background-color: tomato;
z-index: 1000;
}
</style>
<style>
.demo {
width: 100px;
height: 100px;
background-color: tomato;
z-index: 1000;
}
</style>
<body>
<div class="div"></div>
<div class="demo"></div>
</body>
</html>
<script>
var div = document.getElementById("div");
var sheet = document.styleSheets[1];
console.log(sheet);
sheet.insertRule("body {background-color:silver;}", 0); //DOM方法
</script>
3.删除规则
deleteRule():接收一个参数,要删除的规则的位置;
在IE中使用removeRule()方法;
12.2.3 元素大小
偏移量
元素在屏幕上占用的所有可见的空间;
- offsetHeight:元素在垂直方向上占用的空间大小,以像素计;
- offsetWidth:元素在水平方向上占用的空间大小,以像素计;
- offsetLeft:元素的左边外框至包含元素的左内边框之间的像素距离;
- offsetTop:元素的上边边框至包含元素的上内边框之间的像素距离;
offsetWidth
计算方式: content width(CSS设定的width) + padding + border + scrollBarWidth 如果存在垂直滚动条(scrollbar)
offsetHeight
计算方式: content height(CSS设定的height) + padding + border + scrollbarHeight 如果存在水平滚动(scrollbar)
offsetParent
可以理解为偏移的基准, 这有点类似定位属性中(absolute以最近的祖先元素容器且设置了定位属性的元素来进行位置偏移.)
什么样的元素为 offsetParent ?
- 拥有定位属性的元素
- dispaly 为 table 或 table cell
- 默认情况下根元素
依次从内往外找, 如果没有, 默认就是已根元素作为 offsetParent 也就是偏移的基准.
当元素设置属性 display: none, 则它相应的 offsetParent属性返回值为 null.
ps:
如果元素为隐藏的(该元素或其祖先元素的 style.display 为 “none”),或者该元素的 style.position 被设为 “fixed”, 则该 offsetParent 属性返回 null。在 IE 9 中 display:none 无影响.
offsetLeft
返回一个元素(border边框)到 offsetParent 元素左边界(边界可能为边框或内边距)的距离.
offsetTop
返回一个元素(border边框)到 offsetParent 元素上边界(边界可能为边框或内边距)的距离.
客户区大小
元素的客户区大小,指的是元素内容及其内边距所占据的空间大小。
相关属性如下:
-
clientWidth:元素内容区宽度+元素左右内边距
-
clientHeight:元素内容区高度+元素上下内边距
滚动大小
包含滚动内容的元素大小.
- scrollHeight:在没有滚动条的情况下,元素内容的总高度;
- scrollWidth:在没有滚动条的情况下,元素内容的总宽度;
- scrollLeft:被隐藏在内容区域左侧的像素数.
- scrollTop:被隐藏在内容区域上方的像素数.
确定元素大小
getBoundingClientRect()方法
- 兼容性:IE,Firefox 3+,Safari 4+,Opera 9.5及Chrome
这个属性给出了元素在页面中相对于视口的位置
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<style>
html,
body {
padding: 0;
margin: 0;
}
.div {
width: 50px;
height: 50px;
position: absolute;
left: 20px;
top: 10px;
background-color: tomato;
}
</style>
<body>
<div class="div"></div>
</body>
</html>
<script>
var div = document.querySelector(".div");
var rect = div.getBoundingClientRect();
console.log(rect);
</script>
效果:
12.3 遍历
提供两个类型:NodeIterator和TreeWalker,基于给定的起点对DOM结构执行深度优先遍历;
12.3.1 NodeIterator
使用document.createNodeIterator()方法创建:
- root:搜索起点
- whatToShow:访问哪些节点的数字代码
- filter:是一个NodeFilter对象,过滤
- entityReferenceExpansion:布尔值,是否要拓展实体引用
NodeFilter对象类型常量参数: - NodeFilter.SHOW_ALL:显示所有类型的节点
- NodeFilter.SHOW_ELEMENT:显示元素节点
- NodeFilter.SHOW_ATTRIBUTE:显示特性节点
- NodeFilter.SHOW_TEXT:显示文本节点
- NodeFilter.SHOW_CDATA_SECTION:显示CDATA节点
- NodeFilter.SHOW_ENTITY_REFERENCE:显示实体引用节点
- NodeFilter.SHOW_ENTITYE:显示实体节点
- NodeFilter.SHOW_PROCESSING_INSTRUCTION:显示处理指令节点
- NodeFilter.SHOW_COMMENT:显示注释节点
- NodeFilter.SHOW_DOCUMENT:显示文档节点
- NodeFilter.SHOW_DOCUMENT_TYPE:显示文档类型节点
- NodeFilter.SHOW_DOCUMENT_FREGMENT:显示文档片段节点
- NodeFilter.SHOW_NOTATION:显示符合节点
方法:
- nextNode():向前前进一步,内部指针
- previousNode():向后退一步,内部指针
12.3.2 TreeWalker
创建TreeWalker对象要使用document.createTreeWalker()方法,接收4个参数:
- 遍历起点的节点
- 显示的节点类型
- 过滤器
- 是否拓展实体的引用的布尔值
NodeIterator的一个更高级的版本,除了包括nextNode和previousNode相同还包含:
- parentNode():遍历到当前节点的父节点
- firstChild():遍历到当前节点的第一个子节点
- lastChild():遍历到当前节点的最后一个子节点
- nextSibling():遍历到当前节点的下一个同辈节点
- previousSibling():遍历到当前节点的上一个同辈节点
12.4 范围
通过范围可以选择文档中的一个区域,而不必考虑节点的界限
12.4.1 DOM中的范围
使用createRang()方法,可以创建一个范围
每一个范围由一个Range类型实例表示,这个实例拥有很多属性和方法:
- startContainer:包含范围起点的节点
- startOffset:范围在startContainer中起点的偏移量.
- endContainer:包含范围终点的节点
- endOffset:范围在endContainer中终点的偏移量
- commonAncestorContainer:startContainer和endContainer共同的祖先节点在文档树中位置最深的那个
1.用DOM范围实现简单选择
selectNode()或selectNodeContents():都接受一个参数,即一个node节点,然后用该节点信息填充范围
2.用DOM范围实现复杂选择
setStart和setEnd:接收两个参数,一个参考节点和一个偏移量值;
3.操作DOM范围的内容
deleteContents():删除范围中包含的内容
4.插入DOM范围中的内容
insertNode():向范围中的开始处插入一个节点;
5.折叠DOM范围
collapse()方法:接受一个参数,一个布尔值
6.比较DOM范围
compareBoundaryPoints():确定这些范围是否有公共的边界:
- Range.START_TO_START(0):比较低一个范围和第二个范围起点
- Range.START_TO_END(1):比较第一个范围起点和第二个范围的终点
- Range.END_TO_END(2):比较第一个范围和第二个范围的终点
- Range.END_TO_START(3):比较第一个范围终点和第二个范围的起点
7.复制DOM范围
cloneRange()方法
8.清理DOM范围
detach()方法
12.4.2 IE8及更早版本中的范围
1.用IE范围实现简单的选择
findeText()
2.使用IE范围实现复杂的选择
move();
moveStart();
moveEnd();
expand();
3.操作IE范围中的内容
pasteHTML()
4.折叠IE范围
collapsed()
5.比较IE范围
compareEndPoints()
6.复制IE范围
duplicate()