javascript学习笔记——操作样式表、元素大小、客户区大小、滚动大小、NodeIterator、TreeWalker、DOM范围

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baidu_39067385/article/details/81436867

 1.访问元素的样式

任何支持sytle特性的html元素在js中都有一个对应的style属性。style对象包含着通过HTML的style特性指定的所有样式信息,但不包括与外部样式表或嵌入样式表经层叠而来的样式;

css属性将表现为这个style对象的相应属性;

var myDir=document.getElementById("myDir");
//设置背景颜色
myDir.style.backgroundColor="red";
//改变大小
myDir.style.width="100px";
myDir.style.height="200px";
//指定边框
myDir.style.border="1px solid black";

通过属性名取得属性的值

var prop,value,i,len;
for(i=0,len=myDir.length;i<len;i++){
  prop=myDir.style[i];   //或者  myDir.style.item(i);
  value=myDir.style.getPropertyValue(prop);
  alert(prop+":"+value);

  value=myDir.style.getPropertyCSSValue(prop);   //CSSText和cssValueText是搞函数返回对象的两个属性
  alert(prop+":"+value.CSSText+"("+value.cssValueType+")");
}

 getComputedStyle()方法能够取得计算的样式;

第一个参数是计算样式的元素,第二个参数是一个伪元素字符串;

如果不需要伪元素信息,则第二个参数可以是null

var myDir=document.getElementById("myDir");
var computedStyle=document.defaultView.getComputedStyle(myDir,null);
alert(commputedStyle.backgroundColor);    //red

IE不支持getComputedStyle(),但在IE中每个具有style属性的元素都还有一个currentStyle属性,用来取得计算的样式;

var myDir=document.getElementById("myDir");
var computedStyle=MyDir.currentStyle;
alert(commputedStyle.backgroundColor);    //red

2.操作样式表

CSSStyleSheet类型表示的是样式表。继承自StyleSheet;是一套只读的接口;

应用于文档的所有样式表是通过document.styleSheets集合来表示的。通过这个集合的length属性可以获知文档中样式表的数量,而通过方括号语法或item()方法可以访问文档中每一个样式表。

 CSSRule对象表示样式表中的每一条规则,它是一个供其他类型继承的基类型,其中最常见的就是CSSStyleRule类型;

CSSStyleRule对象最常用的三个属性:

①cssText:返回整条规则对应的文本,IE不支持这个属性;

②selectorText:返回当前规则的选择符文本;

③style:一个CSSStyleDeclaration对象,可以通过它设置和取得规则中特定的样式值

div.box{
  background-color:blue;
  width:100px;
  heigth:200px;
}

 假设这条规则位于页面的第一个样式表中,而这个样式表中只有这一条样式规则;

var sheet=document.styleSheet[0];    //取得文档中第一个样式表
var rules=sheet.cssRule||sheet.rules;  //取得样式表中的规则列表
var rule=rules[0];                    //取得第一条规则
alert(rule.selectorText);       //"div.box"
alert(rule.cssText);            //完整的CSS代码
alert(rule.style.width);        //100px

rule.style.backgroundColor="red";     //修改样式信息

 创建规则

InsertRule(规则文本,在哪里插入规则的索引),可以向样式表中添加新规则;

IE以及更早版本支持的是,addRule(选择符文本,css样式信息,插入规则的位置)

最多可以使用addRule()添加4095条规则,否则报错;

 跨浏览器的方式向样式表中插入规则:

//(要插入规则的样式,选择符文本,规则信息,插入位置)
function inserRlue(sheet,selectorText,cssText,position){
   if(sheet.insertRule){
     sheet.insertRule(selectorText+"{"+cssText+"}",position);
  }else if(sheet.addRule){    //IE浏览器
     sheet.addRule(selectorText,cssText,position);
  }
}

insertRule(document.styleSheet[0],"body","background-color:red",0);

删除规则

删除规则的方法时deleteRule(要删除的规则的位置)

IE支持的删除规则的方法:removeRule(要删除的规则的位置)

考虑到删除规则可能影

响css层叠效果,所以要慎用删除规则

跨浏览器删除规则的函数 

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

元素大小

1)偏移量:包括元素在屏幕上占用的所有可见的空间

元素的可见大小由其高度、宽度决定,包括所有的内边距、滚动条和边框大小

以下图形表示跟元素有关的属性的意义

 某个元素在页面上的偏移量等于元素的offsetLeft和offsetTop与其offsetParent的相同属性相加

 取得元素在页面左偏移量的函数:

function getEleementLeft(element){
   var actualLeft=element.offsetLeft;
   var current=element.offsetParent;
   while(current!=null){
     actualLeft+=current.offsetLeft;
     current=current.offsetParent;
    }
   return actualLeft;
}

 取得元素在页面上偏移量的函数:

function getEleementTop(element){
   var actualTop=element.offsetTop;
   var current=element.offsetParent;
   while(current!=null){
     actualTop+=current.offsetTop;
     current=current.offsetParent;
    }
   return actualTop;
}

客户区大小

元素的客户区大小,指的是元素内容及其内边距所占据的空间大小;

客户区的大小就是元素内部空间的大小,因此滚动条占用的空间就不就算在内;

客户区大小是只读的,每次访问都要重新计算;

确定浏览器视口大小使用的函数:

function getViewport(){
    if(doocument.compatMode=="BackCompat"){      //混杂模式,IE7之前的版本
        return{
            width:document.body.clientWidth;
            height:document.body.clientHeight; 
      };
   }else{
       return{
           width:document.documentElement.clientWidth;
           height:document.documentElement.clientHeight;
      };
     
   }
}

滚动大小

滚动大小指的是包含滚动内容的元素的大小;

scrollheight和scrollWidth主要用于确定元素内容的实际大小;

在不包含滚动页面的时候,scrollHeight和scrollWidth与clientHeight和clientWidth之间的关系并不清晰;在这种情况下,基于document.documentEleement查看的这些属性会在浏览器发现一些不一致的问题;

 

 遍历

NodeIterator和TreeWalker这两个类型能够基于给定的起点对Dom结构执行深度优先的遍历操作。

IE不支持DOM遍历;

DOM遍历是深度优先的DOM结构遍历,即移动方向至少有两个。遍历以给定节点为根,不可能向上超出DOM树的根节点。

任何节点都可以作为根节点;

HTML页面:

<!DOCTYPE html>
<html>
  <head>
    <title>example</title>
 </head>
  <body>
     <p><b>hello</b> world!</p>
  </body>
</html>

 展示这个页面DOM结构树

 NodeIterator

创建实例:document.createNodeIterator(root,whatToShow,filter,entityReferenceExpansion)

刚创建的实例有一个内部指针指向根节点;

root:想要作为搜索起点的树中节点;

 whatToShow:表示要访问哪些节点的数字代码;

 filter :是一个NodeFilter对象,或者一个表示应该接受还是拒绝某种特定节点的函数;(如果不指定过滤器,则为null)

entityReferenceExpansion:布尔值,表示是否要扩展实体引用;

 创建一个只显示<p>元素的节点迭代器;

var filter={
  acceotNode:function(node){
     return node.tagName.toLowerCase()=="p"?
                 NodeFilter.FILTER_ACCEPT:  //接收
                 NodeFilter.FILTER_SKIF;         //跳过当前节点到下一个节点
  }   
};

var iterator=document.createNodeIterator(root,NodeFilter.SHOW_ELEMENT,filter,false);

NodeIterator类型有两个操作方法:

1)nextNode() 方法用于向前前进一步;

2)previousNode()方法用于向后退一步

 TreeWalker

TreeWalker是NodeIterator的一个更高的版本;

创建实例:document.createTreeWalker(root,wahtToShow,filter,entityReferenceExansion)

具有的方法:

除了nextNode(),previousNode()方法之外,还有

1)parentNode():遍历当前节点的父节点

2)firstNode():遍历当前节点的第一个子节点;

3)lastChild():遍历当前节点的最后一个子节点;

4)nextSibling():遍历当前节点的下一个同辈节点;

5)previouSibling():遍历当前节点的上一个同辈节点;

6)currentNode属性:表示任何遍历方法在上一次遍历中返回的节点。利用它可以修改遍历继续进行的起点;

TreeWalker真正强大的地方在于在DOM结构中可以沿任意方向移动,使用TreeWalker遍历DOM树,即使不使用过滤器也可以取得某些特定的元素;

var div=document.getElementById("div1");
var filter={
  acceotNode:function(node){
     return node.tagName.toLowerCase()=="li"?
                 NodeFilter.FILTER_ACCEPT:  //接收
                 NodeFilter.FILTER_SKIF;         //跳过当前节点到下一个节点
  }   
};

var walker=document.createTreeWalker(div,NodeFilter.SHOW_ELEMENT,filter,false);
var node=walker.nextNode();
while(node!=null){
   alert(node.tagname);
   node=wakler.nextNode();
}

范围

如果浏览器支持范围,那么就可以是创建范围实例,新创建的范围直接与创建它的文档关联到一起,不能用于其他文档。

创建范围并设置了其位置之后,还可以针对范围的内容执行很多操作,从而实现对底层DOM树的更精准的控制;

每一个范围由一个Range类型的实例表示;

 1、使用范围选择文档的一部分;

selectNode(node):选择的是整个节点,包括其子节点;

selectNodeContents(node):只选择节点的子节点;

var range1=document.createRange();
var range2=document.createRange();
p1.document.getElementById("p1");
range1.aelectNode(p1);
range2.selectNodeContents(p1);

 

 2、用DOM范围实现复杂的选择

setStart(参数节点,偏移量值)

setEnd(参数节点,偏移量)

 选取"hello world!"中的“llo”到“world!”的“o”;

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

 

 在创建范围时,内部会为这个范围创建一个文档片段;会自动补全该范围内缺少的标签;

在使用操作方法之前,拆分的节点并不会产生格式良好的文档片段,原始HTML在DOM被修改之前会始终保持不变;

 比如在前一个例子中修改后的DOM实质上是:

<p id="p1"><b>he</b><b>llo</b> world!</p>

3、操作DOM范围中的内容

1)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();          //从文档中删除该范围

删除后页面变成

<p id="p1"><b>he</b>rld!</p>

2)extractContents():从文档中移除范围,返回范围额文档片段,可以将返回的文档片段加入到文档的其他地方;

var p1=document.getElementById("p1");
helloNode=p1.firstChild.firstChild;
worldNode=p1.lastChild;
var range=document.createRange();
range.setStart(helloNode,2);
range.setEnd(worldNode,3);
var fragment=range.extractContents();
p1.parentNode.appendChild(fragment);

页面变化如下:

<p id="p1"><b>he</b>rld!</p>
<b>llo</b> wo

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

var p1=document.getElementById("p1");
helloNode=p1.firstChild.firstChild;
worldNode=p1.lastChild;
var range=document.createRange();
range.setStart(helloNode,2);
range.setEnd(worldNode,3);
var fragment=range.cloneContents();
p1.parentNode.appendChild(fragment);

页面变化如下:

<p id="p1"><b>hello</b> world!</p>
<b>llo</b> wo

4、插入DOM范围中的内容

1)insertNode():可以向范围中的开始处插入一个节点;

var p1=document.getElementById("p1");
helloNode=p1.firstChild.firstChild;
worldNode=p1.lastChild;
var range=document.createRange();
range.setStart(helloNode,2);
range.setEnd(worldNode,3);
var span=document.createElement("span");
span.style.color="red";
span.appendChild(document.createTextNode("insert node"));
range.insertNode(span);

页面变化如下:

<p id="p1"><b>he<span style="color:red">insert text</span>llo</b> world!</p>

 2)surroundContents():该方法可以环绕范围插入内容;

在环绕范围插入内容是,后台会执行下列步骤:

①提取出范围中的内容;

②将给定的节点插入到文档中的原来位置上;

③将文档片段的内容添加到给定节点中;

var p1=document.getElementById("p1");
helloNode=p1.firstChild.firstChild;
worldNode=p1.lastChild;
var range=document.createRange();
range.setStart(helloNode,2);
range.setEnd(worldNode,3);
var span=document.createElement("span");
span.style.backgroundColor="red";
range.surroundContents(span);

页面变化

<p id="p1"><b>he</b><span style="background-color:red"><b>llo</b> wo</span>rld!</p>

5.折叠DOM范围

使用collapse()方法来折叠范围,这个方法接收一个参数布尔值,表示要折叠到范围的哪一端;

true时表示折叠到范围的起点,即光标定位到范围的起点;

false时表示折叠到范围的终点;

 6、比较DOM范围

compareBoundaryPoints(比较方式的常量值,比较的范围)方法确定这些范围是否有公共的边界(起点或终点)

如果第一个范围中的点位于第二个范围中的点之前,返回-1

如果第一个范围中的点位于第二个范围中的点之后,返回1;

如果两个点相等,返回0;

 7、赋值DOM范围

使用cloneRange()方法复制范围,这个方法会创建调用它范围的一个副本;

var newrange=range.cloneRange();

 8、清理DOM范围

使用完范围之后最好是调用detach()方法,以便从创建范围的文档中分离出该范围,调用detach()之后,就可以放心的解除对范围的引用,从而让垃圾回收机制回收其内存;

range.detach();     //从文档中分离范围
range=null;          //删除引用

IE8及更早版本中的范围

IE9支持DOM范围,但IE8以及更早的版本不支持DOM范围。支持的是文本范围,文本范围是IE的专有特性,其他浏览器都不支持。

文本范围:处理的主要是文本,不一定是DOM节点。

1)创建文本范围:

var range=document.body.createTextRange()

document创建的范围可以在页面的任何地方使用;

2)用IE范围实现简单的选择

①  var found=range.findText("hello");

选择某一区域的最简单的方式,这个方法会找到第一次出现的给定文本,并将范围移过来以围绕该文本。返回布尔值;

 range.text;    //hello

可以得到范围中包含的文本;

③  var frange=range.findText("hello",1);

findText()可以传入第二个参数,一个表示会向哪个方向的继续搜索的数值。负值表示应该从当前位置向后搜索,而正值表示应该向前搜索

④  moveToElement(),这个方法接收一个DOM元素,并选择该元素的所有文本,包括HTML标签;

range.moveToElement(p1);

range.htmlText;

在文本中包含HTML的情况下,可以使用htmlText属性取得范围的全部内容,包括HTML和文本。

IE的范围没有任何属性可以随着范围选区的变化而动态更新;

3)使用IE范围实现复杂的选择

move()、moveStart()、moveEnd()和expand()这些方法可以以特定的增量向四周移动范围。都接收两个参数:移动单位和移动单位的数量;移动单位的类别:

“character”  字符   “word”  单词   sentence   句子       textedit   移动到当前选区开始或结束的位置;

moveStart()可以移动范围的起点        moveEnd()可以移动范围的终点;

range.moveStart("world",2);         //起点移动两个单词

range.moveEnd("character",1);      //终点移动1个字符

4)操作范围中的内容

操作范围中内容可以使用text属性和pasteHTML()

range.pasteHTML("<b>bob</b>");

5)折叠范围

collapse()方法与相应的DOM方法一样,传入true则把范围折叠到起点,传入false则把范围折叠到终点;

range.collapse(true);

6)比较IE范围

compareEndPoints(比较的类型,比较的范围),返回结果与DOM范围的比较是一样的;

range1.compareEndPoints("StartToStart",range2);

isEqual()用于确定两个范围是否相等;

inRange()用于确定一个范围是否包含另个范围;

range1.isEqual(range2);

range1.inRange(range2);

7)复制IE范围

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

var newrange=range.duplicate();

猜你喜欢

转载自blog.csdn.net/baidu_39067385/article/details/81436867