DOM 知识点梳理(笔记)

时间:2021-11-25 23:36:23

  1998年10月DOM1级规范成为了W3C的推荐标准,为基本的文档结构及查询提供了接口。

一、Node类型

  每个节点都有个nodeType属性,表明了节点的类型。共有12种类型:

元素节点                   Node.ELEMENT_NODE(1)

属性节点                   Node.ATTRIBUTE_NODE(2)

文本节点                   Node.TEXT_NODE(3)

CDATA节点                    Node.CDATA_SECTION_NODE(4)

实体引用名称节点        Node.ENTRY_REFERENCE_NODE(5)

实体名称节点             Node.ENTITY_NODE(6)

处理指令节点             Node.PROCESSING_INSTRUCTION_NODE(7)

注释节点                      Node.COMMENT_NODE(8)

文档节点                      Node.DOCUMENT_NODE(9)

文档类型节点            Node.DOCUMENT_TYPE_NODE(10)

文档片段节点            Node.DOCUMENT_FRAGMENT_NODE(11)

DTD声明节点                 Node.NOTATION_NODE(12)

  这12个类型并不完全受到浏览器的支持;而开发人员常用的就是前三个(元素节点,属性节点,文本节点)

 if(someNode.nodeType==3){
//为了兼容ie,通常将noteType的属性值与数值进行比较
}

  此外节点还有nodeNames和nodeValue这两个属性。而这二个属性的值完全取决于节点的类型。

 

1)对于nodeName来说

  元素节点的 nodeName 是标签名称。
  属性节点的 nodeName 是属性名称。
  文本节点的 nodeName 是 #text。
  文档节点的 nodeName 是 #document。

2)对于nodeValue来说

  文本节点的nodeValue 属性包含文本。
  对于属性节点的nodeValue 属性包含属性值。
  文档节点的nodeVlaue为null。
  元素节点是nodeVlaue为null。

1.1节点关系:

  每个节点都有一个childNodes属性,其中保存着一个NodeList对象,它是基于DOM结构动态执行查询的结果而不是一张初次访问时的快照。

  每个节点也都有个parentNode节点,该属性指向文档节点的父节点。childNodes列表中所有的节点都具有相同的父节点。而且它们之间都是同胞节点,可以通过previousSibling和nextSibling互相之间访问,父节点的firstChild和lastChild分别指向childcNodes列表的第一个和最后一个j节点。

1.2操作节点

appendChild()方法:

  用于向父节点的chidNodes末尾添加一个节点。如果传入到appendChild()的节点已经是文档中的一部分了,那么该节点会从原来的位置转移到新的位置上。

例如:

<div id="ss">hi 
<p>1</p>
<p>2</p>
<p>3</p>
</div> <script>
var ss=document.getElementById("ss");
ss.appendChild(ss.firstChild);
alert(ss.lastChild.nodeValue);//hi 第一个文本节点 变成了最后一个节点
</script>

insetBefore()方法:

  这个方法接受二个参数:要插入的节点和作为参照的节点。插入后被插入的节点会变成参照节点的前一个同胞节点。

  如果参照节点是null那么执行和appendChild相同的操作。

replaceChild()方法:

  这个方法接受二个参数:要插入的节点和要替换的节点。返回替换的节点。

removeChild()方法:

  这个方法接受一个参数,即要移除的节点。返回被移除的节点。

上面的四个方法在调用时,都是在某个节点的子节点上操作,所以都必须先取得它们的父节点!

cloneNode()方法:

该方法接受一个布尔型参数表示是否进行深浅负责,为true时执行深复制(复制节点及其整个子节点树),为false时执行浅复制(只复制节点本身)。

var ss=document.getElementById("ss");var tt=ss.cloneNode(true);
  ss.appendChild(tt);//复制完后,为他指定父节点,将它添加到文档中

二、Document类型

  document对象是HTMLDocument的一个实例,表示整个HTMl页面。

  可以通过document.documentElement和document.body来取得对<html>和<body>的引用

文档信息:

document.title包含着<title>元素中文本的引用。

document.URl包含着页面完整的URl。

document.domain包含着页面的域名。它是可读取也可设置的,进而可以对二个页面进行通信设置。

document.referrer保存着链接到当前页面的那个页面的URl。

查找元素:

document.getElementById();

document.getElementsByTagName();

特殊集合:

document.anchors  包含文档中所有带name特性的<a>标签 

document.forms   包含文档中所有的<form>元素

document.images   包含文档中所有的<img>元素

document.links    包含文档中所有带href特性<a>元素

文档写入:

document.write()或writeln()

  可以在页面加载过程中动态的向页面加入内容。

三、Element类型

  Element类型用来表现XML或HTML元素,提供了对元素标签名,子节点及特性的访问。

取得元素的标签名可以使用nodeName或者tagName。

取得特性:

  每个元素都有特性,而操作特性的DOM主要有三个方法:

getAttribute()     一般用它来取得自定义的特性

setAttribute()   如果设置的特性已经存在则以指定的值替换它,如果没有则创建它。

removeAttribute()

创建元素:

document.createElement();

三、Text类型

创建文本节点:

document.createTextNode()

分割文本节点:

splitText()

  小结:DOM将文档形象地看作一个层次化的节点树,可以用js来操作这个节点树,进而改变底层文档的外观和结构。DOM操作往往是js中开销最大的部分,尽量减少DOM操作。

DOM扩展

选择符API

querySelector()  接受一个css选择符,返回与该模式匹配到的第一个元素。

querySelectorAll()  返回的是所有匹配的元素。

与类相关的扩展:

getElementsByClassName()

classList属性

它有如下的方法:

add()    将给定的字符串值添加到列表中,有就不添加。

contains()    表示列表中是否有给定的值,返回布尔值

remove()  从列表中删除给定的字符串。

toggle()  如果列表中存在给定的值则删除它,没有的话则添加它。

焦点管理

document.activeElement属性  这个属性始终会引用DOM中当前获得焦点的元素。

document.hasFocus()方法

自定义数据属性

  h5规定可以为元素添加非标准的属性,只需添加前缀data-。然后可以通过元素的dataset属性来访问自定义属性的值。

innerHTML属性

  读模式下会返回调用元素的所有子节点。写模式下,替换调用元素原来的所有子节点。

contains方法

  该方法用来检测某个节点是不是另外一个节点的子节点。返回布尔值。

插入文本

innerText、outerText属性

  它们都没有被纳入h5的规范。

DOM2和DOM3

   前面讲的DOM1主要定了HTML和XML的文档底层结构而DOM2和DOM3级则在这个结构的基础上引入了更多的交互能力。
 
DOM2级分为如下模块:
 
  DOM Level 2 Core:在1级核心的基础上,为节点添加了更多的方法和属性。
  DOM Level 2 Views:为文档定义了基于样式信息的不同视图。
  DOM Level 2 Events:说明了如何使用事件与DOM进行交互。
  DOM Level 2 Style:定义了如何以编程的方式来访问和改变CSS样式的信息。
  DOM Level 2 Traversal and Range:引入了遍历DOM和选择其特定部分的新接口。
  DOM Level 2 HTML:在一级的HTML上构建添加了更多的属性、方法和新接口。
 

DOM2级样式模块

 
1、访问元素的样式
  任何支持style属性的html元素在javascipt中都有一个对应的style属性,对于使用短划线的css属性名,必须将其转换为驼峰大小的形式:font-size---->fontSzie这样的形式。其中有一个float属性不能直接转换,IE下支持转换为styleFLoat,其他浏览器转换为cssFloat。
 
DOM2级样式模块为style对象定义了一些属性和方法:
 
  cssText:访问style特性中的css代码。
  length:应用给css属性的数量。
  getPropertyValue():返回给定属性的字符串值。
  removeProperty():从样式中删除给定属性。
 
  通过cssText属性,在写模式下会重写整个style属性
 <div id="demo" style="width:200px;height:200px;border:1px solid #599;"></div>

  <script>
var aa=document.getElementById("demo");
document.write(aa.style.cssText);//width: 200px; height: 200px; border: 1px solid rgb(85, 153, 153);
</script>

  设计length的目的就是将其与item()方法配套使用。用for循环获得属性名后就可以进一步用getPropertyValue()来获得属性名的值:

  <div id="demo" style="width:200px;height:200px;border:1px solid #599;"></div>

  <script>

   var  aa=document.getElementById("demo");
var len=aa.style.length,i,prop,value;
  for(i=0;i<len;i++){
prop=aa.style[i];//或者aa.style.item(i);
value=aa.style.getPropertyValue(prop);
document.write(prop+":"+value+"</br>");//竟然有19种属性名,名称是以短划线形式出现,不是驼峰形式。
//width:200px
//height:200px
//border-top-width:1px
//border-right-width:1px
//border-bottom-width:1px
//border-left-width:1px
//border-top-style:solid
//border-right-style:solid
//border-bottom-style:solid
//border-left-style:solid
//border-top-color:rgb(85, 153, 153)
//border-right-color:rgb(85, 153, 153)
//border-bottom-color:rgb(85, 153, 153)
//border-left-color:rgb(85, 153, 153)
//border-image-source:initial
//border-image-slice:initial
//border-image-width:initial
//border-image-outset:initial
//border-image-repeat:initial
}
</script>

  要想删除某个css属性,调用removeProperty()即可:

aa.style.removeProperty("width");//删除后,将应用默认的值

2、计算的样式:

  通过style对象可以访问任何支持style特性的元素的样式信息,但不包括从其他样式表层叠而来而影响到当前元素的样式信息。

  so,DOM2级样式模块增强了document.defaultView,提供了getComputedStyle()方法。这个方法接受二个参数;要取得计算样式的 元素和一个伪元素字符串,如果不需要伪元素则将它设置为null。

看个例子:

  <div id="demo" style="width:200px;height:200px;"></div>
<style>#demo{border:1px solid #789;background:#ccc}</style> <script>
var aa=document.getElementById("demo");
var computedStyle=document.defaultView.getComputedStyle(aa,null);
alert(computedStyle.width);//"200px"
alert(computedStyle.border);//"1px solid #789" //IE不支持getComputedSytle()方法,但是是在IE中支持style属性的元素还有个currentStyle属性
//这个属性包含当前元素计算后的样式
//var computedStyle=aa.currentSytle;
//alert(computedStyle.border);
</script>

元素大小

  偏移量包括元素在屏幕上占用的所有可见空间。元素的可见大小由宽高度来决定,包括内边距,滚动条和边框大小。通过下列四个属性可以获得元素的偏移量。

  offsetHeight:元素在垂直方向上占用的空间大小,包括元素的高度,水平滚动条的高度,上下边框的高度。

  offsetWidth:元素在水平方向上占用的空间的大小,包括元素的宽度,垂直滚动条的宽度,左右边框的宽度。

  offsetLeft:元素的左外边框至包含元素的左内边框之间的像素距离。

  offsetTop:元素的上外边框至包含元素的上内边框之间的像素距离。

DOM 知识点梳理(笔记)

 客户区大小

  元素的客户区表示的是元素内容及其内边距所占据的空间的大小。

 clientWidth和clientHeight分别表示元素内容区宽度加上左右内边距宽度和元素内容区加高度加上上下内边距高度。
DOM 知识点梳理(笔记)
 
  它和偏移量相似,客户区大小也是只读的,每次访问都有重新的计算。
 
 
 
滚动大小
  滚动大小指的是包含滚动内容的元素的大小。
scrollHight:在没有滚动条的情况下,元素内容的总高度。
scrollwidth:在没有滚动的情况下,元素内容的总宽度。
scrollLef:被隐藏在内容区域左侧的像素数。
scrollTop:被隐藏在内容区域上方的像素数。
 
DOM 知识点梳理(笔记)
 
 
 

DOM2级遍历和范围模块  

  “DOM2级遍历和范围”模块定义了两个用于辅助完成顺序遍历DOM结构的类型:NodeIterator和treeWalker。这两个类型能够基于给定的起点对DOM进行深度优先的遍历操作。

nodeIterator类型

  可以使用document.createNodeIterator()方法创建它的一个实例。这个方法接受四个参数:

root:表示想要作为搜索起点的树中的节点。

whatToShwo:表示要访问哪些节点的数字代码。

filter:是一个NodeFilter对象,或是一个表示应该接受还是拒绝某种特性的函数。

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

  whatToShwo参数是一个位掩码,通过应用一个或多个过热器来确定要访问那些节点。这个参数以常量形式在NodeIterator类型中定义。列表如下:

1、NodeFilter.SHOW_ALL:搜索所有节点;
2、NodeFilter.SHOW_ELEMENT:搜索元素节点;
3、NodeFilter.SHOW_ATRRIBUTE:搜索特性节点;
4、NodeFilter.SHOW_TEXT:搜索文本节点;
5、NodeFilter.SHOW_ENTITY_REFERENCE:搜索实体引用节点;
6、NodeFilter.SHOW_ENTITY:搜索实体节点;
7、NodeFilter.SHOW_PROCESSING_INSTRUCTION:搜索PI节;
8、NodeFilter.SHOW_COMMENT:搜索注释节点;
9、NodeFilter.SHOW_DOCUMENT:搜索文档节点;
10、NodeFilter.SHOW_DOCUMENT_TYPE:搜索文档类型节点;
11、NodeFilter.SHOW_DOCUMENT_FRAGMENT:搜索文档碎片节节;
12、NodeFilter.SHOW_NOTATION:搜索记号节点;

  nodeIterator类型的两个主要的方法是nextNode()和previousNode()。前者方法用于向前进一步,而后者方法用于向后后退一步。

下面的代码将遍历div元素的所有元素:

<div id="demo">
<p>hello</p>
<ul><li></li><li></li><li></li></ul>
</div>
<script>
var div=document.getElementById("demo");
var iterator=document.createNodeIterator(div,NodeFilter.SHOW_ELEMENT,null,false);
var node=iterator.nextNode();
while(node!==null){
document.write(node.tagName);// 输出标签名:DIV P UL LI LI LI
var node=iterator.nextNode();
}
</script>

如果不指定过滤器,则第三个参数应该指定为null,如果指定的话我们可以自定义一个过滤器,输出想要的结果:

<script>
var div=document.getElementById("demo");
var filter=function(node){
return node.nodeName.toLowerCase()=="li"?NodeFilter.FILTER_ACCEPT:
                      NodeFilter.FILLTER_SKIP;
};
var iterator=document.createNodeIterator(div,NodeFilter.SHOW_ELEMENT,filter,false);
var node=iterator.nextNode();
while(node!==null){
document.write(node.tagName);// 输出标签名:LI LI LI
var node=iterator.nextNode();
}

TreeWalker类型

它除了有nextNode()和previousNode()还有下面的这些方法:

parentNode():遍历当前节点的父节点;
firstChild():遍历到当前节点的第一子节点;
lastChild():遍历到当前节点的最后一个子节点;
nextSibling():遍历到当前节点的下一个同辈节点;
previousSibling():遍历到当前节点的前一个兄弟节点。

  创建TreeWalker对象要使用document.createTreeWalker()方法,这个方法也接受同样的四个参数:作为搜索起点的根节点,要显示的节点类型,过滤器和表示是否可扩展实体引用的布尔值。

TreeWalker即使不使用过滤器也能够取得遍历到想要的元素。

var div=document.getElementById("demo");
var walker=document.createTreeWalker(div,NodeFilter.SHOW_ELEMENT,null,false);
  walker.firstChild();//转到p元素
  walker.nextSibling();//转到ul元素
var node=walker.firstChild();
while(node!==null){
  document.write(node.tagName);// 输出标签名:LI LI LI
  node=walker.nextSibling();
}

DOM2级事件模块

详细见另一篇笔记