JavaScript学习笔记(11)

来源:互联网 发布:genesis软件 编辑:程序博客网 时间:2024/06/14 18:29

DOM2和DOM3

DOM1主要定义了文档的底层结构,DOM2和DOM3在此基础上引入了更多的交互能力。

  • DOM Level2 Core:在1级核心基础上构建,为节点添加了更多方法和属性。
  • DOM Level2 Views:在文档定义了基于样式信息的不同视图
  • DOM Level2 Events:说明了如何使用事件与DOM文档交互
  • DOM Level2 Style:定义了如何以编程方式获取和设置CSS
  • DOM Level2 Traversal and Range:引入了遍历DOM文档和选择其特定部分的新接口
  • DOM Level2 HTML:添加了更多操作HTML的属性、方法和新接口
  • DOM Level3 XPath:用XPath解析DOM的方法
  • DOM Level3 Load&Save:加载和保存模块

1 DOM增强

DOM2和DOM3继续扩展了DOM API,以满足更多的需求。
可以使用

var supportsDOM2Core = document.implementation.hasFeature("Core",2.0);//用于检测是否支持Level2 Core,同理可以检测其他的模块

1.1 命名空间

在原标签之前加入命名空间并用冒号隔开。

<html xmlns="http://www.w3.org/1999/xhtml">    <head>        <title>XHTML page</title>    </head>    <body>        <svg xmlns="http://www/w3/org/2000/svg" version="1.1" viewBox="0 0 100 100" style="width:100%;height:100%">        </svg>    </body></html>

svg及其子元素以及这些元素的特性都属于"http://www/w3/org/2000/svg"命名空间,即使该文档不是SVG文档,这段代码也是有效的。

不过命名空间只是针对XML和XHTML,和HTML没有什么关系,平常写网页基本用不到。


1.2 DocumentType的变化

DOM2增加了可以访问doctype的字段的方法,这部分的内容很少用得到。
举个实际的例子:

//<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd" [<!ELEMENT name (#PCDATA)>]>alert(document.doctype.publicId);//"-//W3C//DTD HTML 4.01//EN"alert(document.doctype.systemId);//"http://www.w3.org/TR/html4/strict.dtd"alert(document.doctype.internalSubset);//"[<!ELEMENT name (#PCDATA)>]"

1.3 Document类型的变化

DOM2给Document类型新增了一个方法——importNode(),用于从文档中取得一个节点并将其导入到另一个文档中。

这个方法与cloneNode()方法相似,参数也是要复制的节点,以及表示深复制(true,连同子树一起复制)或浅复制(false,仅复制该节点本身)的布尔值。
appendChild()方法需要传入的节点与调用的节点的ownerDocument属性一致,否则会报错;
importNode()会在传入的节点属于不同的文档时返回新节点。

var newNode = document.importNode(oldNode,true);document.body.appendChild(newNode);

DOM2新增了defaultView属性用于指向给定文档的父窗口或父框架,IE用parentWindow属性实现。

var parentWindow = document.defaultView || document.parentWindow;

1.4 Node类型的变化

DOM3引入了2个用于比较节点关系的方法:

  • isSameNode(),用于检测两个节点是否引用同一个对象
  • isEqualNode(),用以检测两个节点属于相同类型,具有相等的属性,相同的特性,相同的子节点
var div1 = document.createElement("div");div1.setAttribute("class","box");var div2 = document.createElement("div");div2.setAttribute("class","box");alert(div1.isSameNode(div1)); //truealert(div1.isSameNode(div2)); //false ,引用的不是同一个对象alert(div1.isEqualNode(div2)); //true

1.5 框架的变化

之前无法直接通过元素取得表示框架内容的文档对象。框架和内嵌框架分别用HTMLFrameElementHTMLIFrameElement表示,在DOM2中赋予了一个新属性——contentDocument,该属性包含一个指向框架内容的文档对象的指针。

var iframe = document.getElementById("myIFrame");var iframeDoc = iframe.contentDocument || iframe.contentWindow.document; //为兼容IE

2 样式

在HTML中定义样式的方法有3种:

  • 使用<link />元素包含外部CSS文件
  • 使用<style />元素定义内嵌样式
  • 使用style特性定义针对特定元素的样式

2.1 访问元素的样式

任何支持style特性的HTML元素在JS中都有一个对应的style属性。
style对象是CSSStyleDeclaration的实例,包含了通过HTML的style特性指定的所有样式信息,但不包含与外部样式表或嵌入样式表层叠而来的样式。

var specialDiv = document.getElementById("specialDiv");specialDiv.style.backgroundColor = "red";specialDiv.style.height = "200px";specialDiv.style.border = "1px solid black";alert(specialDiv.style.width);

2.1.1 DOM样式属性和方法

DOM2为style对象定义了一些属性个方法用于访问和修改样式。

名称 说明 cssText 用于访问style特性中的CSS代码
读模式:返回CSS代码
写模式:将style特性值整体替换为参数给定的值 length与item(index) 返回该元素的CSS属性的数量,与item()配合取得特定位置的属性的名称 parentRule 表示CSS信息的CSSRule对象 getPropertyCSSValue() 返回给定属性值的CSSValue对象(包括属性的字符串值cssText和一个数值常量cssValueType)
0-继承的值
1-基本的值
2-值列表
3-自定义值 getPropertyPriority() 返回给定属性值的优先级(“important”或null) getPropertyValue() 返回给定属性的字符串值 setProperty() 设置给定属性的值和优先级 removeProperty() 删除给定的属性,结果是该元素将应用默认的样式
specialDiv.style.cssText = "width:200px;height:200px;background-color:red"; //写模式alert(specialDiv.style.cssText); //读模式var prop, value, i, len;for(i=0 ,len=specialDiv.style.length; i < len; i++){    prop = specialDiv.style.item(i); //也可以使用[i]访问,得到第i个属性的名称    value = specialDiv.style.getPropertyValue(prop); //根据名称取得属性值    alert(prop+":"+value);}

2.1.2 计算的样式

由于style不包含那些从其他样式表层叠而来的样式信息,不能直接通过style访问,因此,要获取该样式需要经过回溯和计算。

DOM2为document.defaultView提供了getComputedStyle()方法,该方法返回一个CSSStyleDeclaration对象,包含了当前元素的所有计算的样式。(IE中使用currentStyle有一样的效果)

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

但是对于不同的浏览器,处理综合属性(例如,border、margin、padding等)的时候有不同返回的结果,可以使用更细化的访问方法(borderLeftWidth来访问border-left-width属性)。

计算样式都是只读的,不能修改计算后样式对象中的CSS属性。
要想在不同平台上有一致的效果,最好手工设置需要的值,计算后的样式包含浏览器内设的默认属性,由于浏览器的不同,默认值也有差异。


2.2 操作样式表

CSSStyleSheet类型表示样式表,继承自StyleSheet,包含了一些操作CSS的属性:

名称 说明 disabled 表示样式是否被禁用,唯一可写的属性,true表示禁用 href 样式表的URL,如果不是link包含的,则为null media 表示当前样式表支持的媒体类型的集合。如果为空列表,表示适用于所有媒体 ownerNode 指向拥有当前样式表的节点的指针,对@import导入的样式表,该值为null
IE不支持 parentStyleSheet 对于@import导入的样式表,这个属性是指向拥有导入它的样式表的指针 title ownerNode中title属性的值 type 表示样式表类型的字符串(”type/css”) cssRules 样式表中包含的样式规则的集合
IE使用rules属性 ownerRule 如果样式表通过@import导入的,这个属性是一个指向表示导入的规则的指针,否则为null
IE不支持 insertRule(rule,index) 在cssRules中指定位置插入rule字符串
IE使用addRule()
这种方法在处理大量添加的时候很繁琐,使用动态加载样式会更好(笔记9的3.2小节) deleteRule(index) 删除cssRules特定位置的规则
IE使用removeRule()
删除规则可能会影响到CSS的级联效果,使用要谨慎

应用于文档的样式表通过document.styleSheets集合表示


2.2.1 CSSRule

CSSRule对象表示样式表中的每一条规则,其最常见的子类是CSSStyleRule类型,该类型包含如下属性(IE基本都不支持):

属性 说明 cssText 返回整条规则对应的文本 parentRule 如果这个规则是导入的,这个属性引用的就是导入规则,否则为null parentStyleSheet 当前规则所属的样式表 selectorText 返回当前规则对应的选择符文本 style 一个CSSStyleDeclaration对象,用于获得和设置规则中特定的样式值 type 表示规则类型的常量值,1表示样式规则
/*对于下列样式,假设位于页面中的第一个样式表中,且该样式表就这一个样式规则div.box {    background-color : blue;    width : 100px;}*/var sheet = document.styleSheets[0];        //取得第一个样式表var rules = sheet.cssRules || sheet.rules;  //取得规则列表,兼容IEvar rule = rules[0];                        //取得列表中的第一条规则alert(rule.cssText);                        //整条CSS规则,包含选择符alert(rule.selectorText);                   //"div.box"alert(rule.style.cssText);                  //CSS规则,只包含花括号内的内容alert(rule.style.width);                    //"100px"rule.style.backgroundColor = "red";         //修改属性值,该修改会影响到所有使用该规则的元素上

2.3 元素大小

DOM没有规定如何确定页面中元素的大小。


2.3.1 偏移量
偏移量包括了元素在屏幕上占用的所有可见的空间,元素的可见大小由其高度、宽度决定,包括内边距、滚动条、边框的大小。

  • offsetHeight,元素在垂直方向上占用的空间大小,单位像素,包括元素高度、(可见的)水平滚动条的高度、上下边框的高度
  • offsetWidth,元素在水平方向上占用的空间大小,单位像素,包括元素宽度、(可见的)垂直滚动条的宽度、左右边框的宽度
  • offsetLeft,元素的左外边框至包含元素的左内边框之间的像素距离
  • offsetTop,元素的外边框至包含元素的额上内边框之间的像素距离

示意图如下:
偏移量示意图【摘自《JavaScript高级程序设计(第3版)》】
【摘自《JavaScript高级程序设计(第3版)》】

通过向上回溯累加offsetLeft和offsetTop可以得到比较准确的元素在页面中的偏移位置。

function getElementTop(ele) {    var actualTop = element.offsetTop;    var current = element.offsetParent;    while(current !== null) { //向上回溯至root        actualTop += current.offsetTop;        current = current.offsetParent;    }    return actualTop;}

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

  • clientWidth,包括元素内容区宽度、左右内边距宽度
  • clientHeight,包括元素内容区高度、上下内边距高度

示意图如下:
客户区示意图【摘自《JavaScript高级程序设计(第3版)》】
【摘自《JavaScript高级程序设计(第3版)》】

function getViewport(){    if (document.compatMode == "BackCompat"){//混杂模式为兼容IE        return {            width:document.body.clientWidth,            height:document.body.clientHeight        };    } else {        return {//返回浏览器视口(html或body元素)的大小            width:docuemnt.documentElement.clientWidth,            height:docuemnt.documentElement.clientHeight        };    }}

2.3.3 滚动
滚动包含滚动内容的元素的大小。有的元素即使没有执行任何代码也会自动添加滚动条,有的元素需要设置overflow属性才能滚动。

  • scrollHeight,在没有滚动条的情况下,为元素内容的总高度
  • scrollWidth,在没有滚动条的情况下,为元素内容的总宽度
  • scrollLeft,被隐藏在内容区左侧的像素数,通过设置可以改变元素的滚动位置,初始为0,如果被水平滚动则值会大于0,该值为元素左侧不可见内容的宽度
  • scrollTop,被隐藏在内容区上方的像素数,通过设置可以改变元素的滚动位置,初始为0,如果被垂直滚动则值会大于0,该值为元素上方不可见内容的宽度

示意图如下:
滚动示意图【摘自《JavaScript高级程序设计(第3版)》】
【摘自《JavaScript高级程序设计(第3版)》】


2.3.4 确定元素大小
getBoundingClientRect()方法用于确定元素的大小,返回一个矩形对象,包含left、top、ringt、bottom。这些属性表示元素在页面中相对于视口的位置。


3 遍历

DOM2提供了用于辅助完成遍历的类型:NodeIterator、TreeWalker。
可以从给定的起点对DOM进行深度优先的遍历操作。


3.1 NodeIterator

这个类型可以使用document.createNodeIterator()方法创建实例。
参数有4个:

  • root:搜索的起点
  • whatToShow:表示要访问哪些节点的数字代码(SHOW_ALL、SHOW_ELEMENT、SHOW_TEXT等等,可以用按位或的方法组合使用)
  • filter:一个NodeFilter对象,或者一个表示过滤特定节点的规则的函数,null表示无过滤
  • entityReferenceExpansion:布尔值,表示是否扩展实体引用,在HTML中没有用
var filter = {    acceptNode: function(node){        return node.tagName.toLowerCase() == "p"?                NodeFileter.FILTER_ACCEPT:                NodeFiler.FILTER_SKIP;    }};var iterator = document.createNodeIterator(root,NodeFilter.SHOW_ELEMENT,filter,false);var node = iterator.nextNode();while(node !== null) {    alert(node.tagName);    node = iterator.nextNode(); //循环迭代输出标签名}

该类型有2个主要的方法nextNode()previousNode(),用于前进和后退。


3.2 TreeWalker

TreeWalker比NodeIterator更高级。除了有nextNode()previousNode(),还实现了其他方向的遍历。

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

使用document.createTreeWalker()方法创建对象,参数和document.createNodeIterator()一样。不过filter返回值还有NodeFilter.FILTER_REJECT,该值会跳过该节点以及该节点的整个子树。


4 范围

DOM2定义了范围接口,便于控制页面。
通过范围可以选择文档中的一个区域,不必考虑节点的界限。


4.1 创建范围

DOM2在Document类型中定义了createRange()方法,用于创建范围。创建的range实例有下列属性用于提供当前范围在文档中的位置信息:

  • startContainer:范围中第一个节点的父节点
  • startOffset:范围在startContainer中起点的偏移量,如果startContainer是文本、注释节点,则该值是范围起点之前跳过的字符数量,否则该值是第一个子节点的索引
  • endContainer:范围中最后一个节点的父节点
  • endOffset:范围在endContainer中终点的偏移量,规则和startOffset相同
  • commonAncestorContainer:startContainer和endContainer的最深的公共祖先节点。

4.2 选择DOM范围

range实例可以使用下列方法选择内容添加进范围:

方法 说明 selectNode(node) 选中整个node节点及其子节点 selectNodeContents(node) 选中node节点的子节点 setStartBefore(refNode) 将refNode设置为范围的起点 setStartAfter(refNode) 将refNode的后一个节点设置为范围的起点 setEndBefore(refNode) 将refNode的前一个节点设置为范围的终点 setEndAfter(refNode) 将refNode设置为范围的终点 setStart(refNode,offset) 将refNode的offset位置作为范围的起点 setEnd(refNode,offset) 将refNode的offset-1位置作为范围的终点

创建范围的同时会补齐范围起点和终点的标签使得即使拿掉整个范围,DOM树也是完整的。


4.3 操作DOM范围

方法 说明 deleteContents() 从文档中删除范围所包含的内容,类比“删除” extractContents() 从文档中删除范围所包含的内容,并返回被删掉的部分,用于插入其他地方,类比“剪切” cloneContents() 创建范围对象的副本,用于插入其他地方,类比“复制” insertNode(node) 将node节点插入到范围的起点之前 surroundContents(node) 将范围包含在node节点中 collapse(bool) 折叠范围,true表示折叠到起点,false折叠到终点,用range.collapsed检测一个范围是否被折叠 compareBoundaryPoints(method,range) 比较调用者和参数中range的边界,返回-1,0,1代表调用者的边界在range边界的之前、相等、之后,method值为Range.START_TO_END代表比较调用者范围的起点和参数范围的终点,同理还有其他三种method cloneRange() 创建一个新的 Range 对象,表示与调用者相同的文档范围 detach() 将范围从文档分离,解除对范围的引用
0 0
原创粉丝点击