DOM2和DOM3

一、DOM的变化

  • DOM2级核心
  • DOM2级视图
  • DOM2级事件
  • DOM2级样式
  • DOM2级遍历和范围
  • DOM2级的HTML

二、样式

2.1、访问元素的样式

任何支持style特性的HTML元素在javascript中都有一个对应的style属性。对于使用短划线的css属性ming,必须将其转化为驼峰大小的形式,才能通过Javascript访问
其中float属性,“DOM级样式”规范规定样式对象上相应的属性名是cssFloat,但是IE浏览器支持的是styleFloat

var myDiv=document.getElementById("myDiv")
myDiv.style.backgroundColor="red";
myDiv.style.width="100px"
myDiv.style.height="100px"myDiv.style.border="1px solid black"
2.1.1、DOM样式属性和方法
  • cssText:访问到style特性中的css代码
  • length:元素CSS属性的数量
  • parentRule:表示css信息的CSSRule对象
  • getPropertyCSSValue(propertyName):返回包含给定属性值cssValue类型(用地少)
  • getPropertyPriority(propertyName):如果给定的属性使用了!important设置,则返回“important”,否则,返回空字符串
  • getPropertyValue(propertyName):返回给定属性的字符串值
  • item(index):返回给定位置的CSS属性的名称
  • removeProperty(propertyName):从样式中删除给定属性
  • setProperty(propertyName,value,priority)
//cssText
myDiv.style.cssText="width:25px;height:100px;background-color:green"
console.log(myDiv.style.cssText)//width: 25px; height: 100px; background-color: green;
//获取属性
for(var i=0,len=myDiv.style.length;i<len;i++){
// console.log(myDiv.style[i])
console.log(myDiv.style.item(i))//width height background-color}
//获取属性值
var prop,value,i,len;
for(var i=0,len=myDiv.style.length;i<len;i++){
prop=myDiv.style[i]
value=myDiv.style.getPropertyValue(prop);
console.log(prop+":"+value)//width: 25px; height: 100px; background-color: green;}
//删除属性值
myDiv.style.removeProperty("width")
//设置属性值
myDiv.style.setProperty("width","100px")
2.1.2、计算的样式

getComputedStyle()方法:这个方法接收两个参数,要取得计算样式的元素和一个伪字符串,如果不需要伪字符串,第二个参数可以是null,返回一个对象(与style属性的类型相同),其中包含当前元素的所有计算样式

var computerdStyle=document.defaultView.getComputedStyle(myDiv,null);

但IE浏览器不指出,它支持currentStyle属性

var computerdStyle=myDiv.currentStyle

2.2、操作样式表

CSSStyleSheet类型表示的是样式表,包括通过元素包含的样式表和在style元素中定义的样式表
document.styleSheets集合表示文档的所有样式表

for(var i=0,len=document.styleSheets.length;i<len;i++)
{
sheet=document.styleSheets.item(i);
console.log(sheet)//CSSStyleSheet {ownerRule: null, type: "text/css", href: "file:///F:/%E4%BB%A3%E7%A0%81%E6%96%87%E4%BB%B6/js%E9%AB%98%E7%BA%A7/style.css", ownerNode: link, parentStyleSheet: null, …}}

另外,也可以通过或者

2.2.1、CSS规则

CSSRule对象表示样式中地每一条规则,实际上,CSSRule是一个供其他多种类型继承的基类型,其中最常见的就是CSSStyleRule类型,包括以下属性

  • cssText:返回整条规则对应的文本
  • parentRule:如果是当前规则是导入的规则,这个属性引用的就是导入规则,否则,这个值为null
  • parentStyleSheet:当前规则所属的样式表
  • selectorText:返回当前规则的选择符文本
  • style:一个CSSStyleDeclaration对象
  • type:表示规则类型的常量值
var sheet=document.styleSheets[0];
var rules=sheet.cssRules||sheet.rules;//取得规则列表var
rule=rules[0];//取得第一条规则
console.log(rule.selectorText);//#myDiv
console.log(rule.style.cssText)//width: 100px; height: 200px; background-color: blue;
console.log(rule.style.backgroundColor)//blueconsole.log(rule.style.width)//100px
console.log(rule.style.height)//200px
2.2.2、创建规则

DOM规定,insertRule()方法:这个方法接收两个参数:规则文本和表示在哪里插入规则的索引
IE8以及之前的版本支持类似的方法,addRule():同样接收两个参数要想跨浏览器使用,可以引入如下函数

function insertRule(sheet,selectorText,cssText,position)
{
if(sheet.insertRule){        sheet.insertRule(selectorText+"{"+cssText+"}",position);
}else if(sheet.addRule){
sheet.addRule(selectorText,cssText,position)
}
}
2.2.3、删除规则

deleteRule():接收一个参数,要删除的规则的位置
DOM方法:deleteRule()
IE方法:removeRule()
跨浏览器的方法如下

function deleteRule(sheet,index){
if(sheet.deleteRule){
sheet.deleteRule(index)
}else if(sheet.removeRule){
sheet.removeRule(index)
}
}

2.3、元素大小

2.3.1、偏移量

包括元素在屏幕上占用的所有可见空间,元素的可见大小由其高度,宽度决定,包括所有的内边距,滚动条,边框大小
在这里插入图片描述

以上四个属性可以得到其偏移量

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.3.2、客户区大小

元素的客户区大小,指的是元素内容以及其内边距所占据的空间大小
在这里插入图片描述

function getViewport(){
if(document.compatMode=="BackCompat"){//混杂模式(IE7之前的版本
return{
width:document.body.clientWidth,
height:document.body.clientHeight
}
}else{//标准模式
return{
width:document.documentElement.clientWidth,
height:document.documentElement.clientHeight
}
}
}
2.3.3、滚动大小

滚动内容的元素的大小
在这里插入图片描述
在确定文档的总高度时,必须取得scrollWidth/clientWidth和scrollHeight/clientHeight的最大值,才能保证在跨浏览器的环境下得到精确的结果

var docHeight=Max.max(document.documentElement.scrollHeight,document.documentElement.scrollWidth)
var docWidth=Max.max(document.documentElement.scrollWidth,document.documentElement.clientWidth)
2.3.4、确定元素的大小

getBoundingClientRect():返回一个矩形对象,包含四个属性:left,top,right,bottom

var rectObject = myDiv.getBoundingClientRect();console.log(rectObject)//DOMRect {x: 8, y: 8, width: 100, height: 200, top: 8, right:108,bottom:208,left:8}

考虑兼容性的写法

//见书p326

三、遍历

3.1、 NodeIterator

两个主要的方法是nextNode()和previousNode()
可以使用document.createNodeIterator()方法创建它的实例
这个方法接受下列四个参数:
root:想要作为搜索起点的树的节点
whatToshow:表示想要访问节点的数字代码
filter:是一个NodeFilter对象,或者表示一个应该接受还是拒绝某种特定节点的函数,每个NodeFilter只有一个方法,即acceptNode(),如果应该访问给定的节点,返回NodeFilter.FILTER_ACCTPT,如果不用改访问,返回NodeFilter.FILTER_SKIP
entityReferenceExpansion:布尔值,表示是否扩展实体引用。

 var div = document.getElementById("div1");
 var iterator = document.createNodeIterator(div, NodeFilter.SHOW_ELEMENT,null, false);
 var node = iterator.nextNode();
 while (node !== null) {
 console.log(node.tagName)//DIV P B UL LI LI LI
 node = iterator.nextNode();               }

如果只需要遍历出li元素,则使用filter

var filter={
acceptNode:function(node){
return node.tagName.toLowerCase()=="li"? 
NodeFilter.FILTER_ACCEPT:
NodeFilter.FILTER_SKIP;
}
}
var div = document.getElementById("div1");
var iterator = document.createNodeIterator(div, NodeFilter.SHOW_ELEMENT,null, false);
var node = iterator.nextNode();
while (node !== null) {
console.log(node.tagName)//DIV P B UL LI LI LI 
node = iterator.nextNode();               }

3.2、TreeWalker

除了nextNode()和previousNode()外,还有其他几个方法:

  • parentNode():遍历到当前父节点
  • firstChild():遍历到当前节点的第一个子节点
  • lastChild():遍历到当前节点的最后一个子节点
  • nextSibling():遍历当前节点的下一个同辈节点
  • previousSibling():遍历当前节点的上一个同辈节点
    创建TreeWalker对象要使用document.createTreeWalker()方法,参数与document.createnodeIterator()相同。
    不同的是,除了NodeFilter.FILTER_SKIP和NodeFilter.FILTER_ACCEPT外,还可以使用NodeFilter.FILTER_REJECT,其中NodeFilter.FILTER_SKIP会跳过相应的节点继续前进到子树的下一节点,NodeFilter.FILTER_REJECT会直接跳过整个的子树
    当然,TreeWalker真正强大的地方在于能够在DOM结构中任何方向移动,即使不定义过滤器,也可以获取所有的li元素
 var div = document.getElementById("div1");
 var walker = document.createTreeWalker(div, NodeFilter.SHOW_ELEMENT,null, false);
walker.firstChild();
walker.nextSibling()
var node=walker.firstChild();
while(node!==null){
console.log(node.tagName);
node=walker.nextSibling()               }

TreeWalker还有一个属性,名叫currentNode,表示任何遍历方法在上一次遍历返回中的节点

 var node=walker.nextNode();
 console.log(node===walker.currentNode)//true

四、范围

4.1、DOM中的范围

document.createRange()创建范围
每个范围都由一个Range类型的实例表示,这个实例拥有很多属性和方法。下列属性提供了当前范围在文档中的位置信息
startContainer:包含范围起点的节点
startOffset:范围在startContainer中起点的偏移量
endContainer:包含范围终点的节点
endOffset:范围在endConstiner中终点的偏移量
commonAncestorContainer:startContainer和endContainer共同祖先节点在文档树中位置最深的那个

4.1.1、用DOM范围实现简单选择

最简单的是使用selectNode()或者selectNodeContents(),这两个方法都接受一个参数,一个DOM节点,然后使用该节点中的信息来填充范围,其中selectNode()选择整个节点,包括其子节点,而selectNodeContents()选择节点的子节点

var range1=document.createRange(),
range2=document.createRange(),
p1=document.getElementById("p1");
range1.selectNode(p1);
range2.selectNodeContents(p1)
console.log(range1)//
startContainer: body
// startOffset: 1
// endContainer: body
// endOffset: 2
// collapsed: false
// commonAncestorContainer: body
// __proto__: Range
console.log(range2)
//     startContainer: p#p1
// startOffset: 0
// endContainer: p#p1
// endOffset: 2
// collapsed: false
// commonAncestorContainer: p#p1
// __proto__: Range
4.1.2、用DOM范围实现复杂选择

要创建复杂的选择就要使用setStart()和setEnd(),这两个方法都接受两个参数:一个参照节点和一个偏移量值

模仿selectNode()和selectNodeContents()

  var range1=document.createRange(),
  range2=document.createRange(), 
  p1=document.getElementById("p1"),
  p1Index=-1,
  i,len;
  for(i=0,len=p1.parentNode.childNodes.length;i<len;i++)
  {
  if(p1.parentNode.childNodes[i]==p1){
  p1Index=1;
  break;
  }
  }
  range1.setStart(p1.parentNode,p1Index);
  range1.setEnd(p1.parentNode,p1Index+1);
  range2.setStart(p1,0);
  range2.setEnd(p1,p1.childNodes.length)
  console.log(range1)
  console.log(range2)

他们更胜一筹的是可以选择节点的一部分

//选择hello world中的llo wo
var p1=document.getElementById("p1"),
helloNode=p1.firstChild.firstChild,
worldNode=p1.lastChild;
var range=document.createRange();
range.setStart(helloNode,2);
range.setEnd(worldNode,3)
4.1.3、操作DOM范围中的内容

在前面创建的文档片段中,选区分别开始和结束于两个文本标签的内部,因此不能算格式良好的DOM结构,但是,范围知道自己缺少哪些开标签和闭标签,能够重新构建有效的DOM结构

从文档中删除范围内所包含的内容deleteContents()

var p1=document.getElementById("p1"),
helloNode=p1.firstChild.firstChild,
worldNode=p1.lastChild;
var range=document.createRange();
range.setStart(helloNode,2);
range.setEnd(worldNode,3)range.deleteContents()//Herld!

执行上述代码后,页面会显示如下HTML代码:

Herld!

由于范围选区在修改底层DOM结构是能够保证格式良好,因此,即使内容被删除了,最终的DOM结构依旧是良好的。

extractContent()也会从文档中移除范围选区,但是这两个方法的区别在于,extractContent()会返回范围的文档片段

...
var fragment=range.extractContents();p1.parentNode.appendChild(fragment)

结果页面的HTML代码为

Herld!

llowo

cloneContents()创建范围对象的一个副本,然后在文档的其他地方插入该文档的副本

...
var fragment=range.cloneContents()
p1.parentNode.appendChild(fragment)

结果页面的HTML代码为

Hello world!

llo wo #### 4.1.4、插入DOM范围中的内容 insertNode():向范围选区的开始处插入一个节点
var span=document.createElement("span");
span.style.color="red";
span.appendChild(document.createTextNode("Inserted text"));r
ange.insertNode(span)

在这里插入图片描述
surroundContents(),这个方法环绕插入内容,这个方法接受一个参数,即环绕范围内容的节点

range.selectNode(helloNode);
var span=document.createElement("span");
span.style.backgroundColor='yellow';
range.surroundContents(span)

在这里插入图片描述

4.1.5、折叠DOM范围

collapse():用来折叠范围,这个方法接受一个参数,一个布尔值,表示要折叠到范围的那一端。参数true表示折叠到范围的起点,参数false表示折叠到范围的终点,要确定范围已经折叠完毕,可以检查collapsed属性

range.collapse(true)
console.log(range.collapse)

检测某个范围是否处于折叠状态,可以帮我们确定范围中的两个节点是否紧邻。

<p id="p1">Paragraph 1</p><p id="p2">Paragraph 2</p>
var p1=document.getElementById("p1"),
p2=document.getElementById("p2"),
range=document.createRange()range.setStartAfter(p1);
range.setEndBefore(p2)console.log(range.collapsed)//true
4.1.6、比较DOM范围

在多个范围的情况下,可以使用compareboundaryPoints()方法来确定这些范围是否公共的边界(起点或者终点),这个方法接受两个参数:比较范围的常量和要比较的范围
范围常量:
Range.START_TO_START(0)
Range.START_TO_END(0)
Range.END_TO_END(0)
Range.END_TO_START(0)
compareBoundaryPoints()方法的返回值:如果第一个范围在第二个范围前面,返回-1,相等,返回0,之后,返回1

var range1=document.createRange()
var range2=document.createRange()
var p1=document.getElementById("p1");
range1.selectNodeContents(p1);
range2.selectNodeContents(p1)
range2.setEndBefore(p1.lastChild)
console.log(range1.compareBoundaryPoints(Range.START_TO_START,range2));
//0
console.log(range1.compareBoundaryPoints(Range.END_TO_END,range2))//1
4.1.6、复制DOM范围

可以使用clonerange(),这个方法会创建调用它的范围的一个副本

var newRange=range.clineRange()

新创建的范围与原来的范围包含相同的属性,而修改他的端点不会影响原来的范围

4.1.7、清理DOM范围

detach(),以便从创建的文档中分离出该范围

4.2、IE8及更早版本中的范围

createTextRange():创建文本范围

4.2.1、用IE范围实现简单的选择

findText():两个参数,给定的文本以及0或1(表示向那个方向搜索)这个方法会找到第一次出现的给定文本,并将范围移过来以环绕文本,如果没有找到文本,就返回false,否则返回true

var range=document.body.createTextRange();
var found=range.findText("hello")
console.log(found);//true
console.log(range.text)//hello

IE中,与selectNode()方法类似的方法是moveToElementText(),这个方法接受一个DOM元素,并选择该元素的所有文本,包括HTML标签

var range=document.body.createTextRange();
var p1=document.getElementById("p1");
range.moveToElementText(p1)
4.2.2、使用IE范围实现复杂的选择

move():首先会折叠当前范围,在将范围移动指定的单位数量
moveStart()
moveEnd()
expand():将任何部分选择的文本全部选中
这些方法都接受两个参数:移动单位和移动单位的数量,其中,移动单位是下列一种字符串。

  • character:逐个字符移动
  • word:逐个单词移动
  • sentence:逐个句子移动
  • textedit:移动到当前范围选区的开始挥着结束位置
range.movestart("word",2);//起点移动两个单词
range.moveEnd("character",1)//终点移动一个字符
4.2.3、操作IE范围中的内容

text属性或者pasteHTML()方法
text可以设置文本的内容

var range=document.body.createTextRange();
range.findText("Hello");
range.text="howdy"

在这里插入图片描述
pasteHTML()向范围内插入HTML代码

var range=document.body.createTextRange();
range.findText("Hello");
range.pasteHTML("<em>Howdy</em>")

在这里插入图片描述

4.2.4、折叠IE范围

collapes()用法与前面相同,但是没有对应的collapsed属性让我们知道乏味是否已经折叠完毕,为此,必须使用boundingWidth属性,该属性返回范围的宽度,如果属性为0,则表示已经折叠了

var isCollapsed=(range.boundingWidth==0)
4.4.5、比较IE范围

compareEndPoints()接受两个参数:比较的类型和要比较额范围,要比较的类型是:StsrtToStart,StartToEnd,StartToEnd,StartToStart
同样与DOM类似的是,它也会按照相同的规则返回值,如果第一个范围在第二个范围前面,返回-1,相等,返回0,之后,返回1
IE中还有两个方法,也是用来比较范围的:isEqual()用于确定两个范围是否相等,inRange()用于确定一个范围是否包含另一个范围

var range1=document.body.createTextRange();
var range2=document.body.createTextRange();
range1.findText("Hello World");
range2.findText("Hello");
console.log(range1.isEqual(range2));//false
console.log(range1.inRange(range2))//true
4.4.6、复制IE范围

duplicate()方法可以复制文本范围,结果会创建原范围的一个副本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值