JavaScript高级程序设计笔记 16

第16章 DOM2 和 DOM3

1. DOM 发展概述

  • DOM1:核心(Core)和 HTML(HTML)模块。
  • DOM2:在 DOM1 基础上扩展了以下模块:
    • DOM 视图(Views):描述追踪文档各种视图的接口。
    • DOM 事件(Events):事件与事件处理(已在第15章详细介绍)。
    • DOM 样式(Style):操作元素样式信息的接口。
    • DOM 遍历与范围(Traversal and Range):遍历和操作 DOM 树的接口。
  • DOM3:进一步扩展,增加加载与保存(Load and Save)、验证(Validation)等模块。

2. DOM 核心(Core)的扩展

2.1 节点类型的变化

  • Node 类型增加了以下方法(DOM3):
    • isSameNode(node):判断两节点是否相同(引用相同)。
    • isEqualNode(node):判断两节点是否相等(类型、属性、子节点均相同)。
    • compareDocumentPosition(node):返回一个位掩码,描述两节点的文档位置关系。
    • getFeature(feature, version)(已废弃)。
  • Document 类型:
    • importNode(node, deep):将外部文档的节点复制一份,纳入当前文档(常用于复制跨文档节点)。
    • createDocument(namespaceURI, qualifiedName, doctype):创建新文档(XML 文档)。
    • createDocumentType(qualifiedName, publicId, systemId):创建文档类型节点。
  • Element 类型:
    • setAttributeNS()getAttributeNS()removeAttributeNS() 等命名空间相关方法(操作 XML 命名空间)。
  • 命名空间支持:XML 命名空间(如 <x:svg>)相关方法只在 XML 文档中必要,在 HTML 文档中很少使用。

3. DOM 样式(Style)

3.1 访问元素样式

  • element.style 对象(CSSStyleDeclaration 实例)表示元素内联样式。
    • 读取:element.style.propertyName(属性名驼峰式,如 backgroundColor)。
    • 设置:element.style.propertyName = value
    • 注意:只能获取/修改内联样式,无法获取外部/内嵌样式表定义的样式。
  • element.style.cssText:批量设置内联样式字符串。
  • element.style.lengthitem(index)getPropertyValue(name) 等方法可遍历内联样式。

3.2 计算样式

  • getComputedStyle(element, pseudoElement) 方法(属于 document.defaultView)。
    • 返回只读的 CSSStyleDeclaration 对象,包含元素最终计算的样式(包括浏览器默认样式、外部样式表等)。
    • 第二个参数可选,用于获取伪元素样式(如 :before)。
  • currentStyle(仅 IE,已不推荐)。

3.3 操作样式表

  • document.styleSheets:获取文档中所有样式表的集合(StyleSheetList)。
  • 每个样式表对象(CSSStyleSheet)具有以下属性:
    • disabled:可读写,启用/禁用样式表。
    • hreftitleownerNodetype 等。
    • cssRules(IE 中为 rules):获取样式规则列表(CSSRuleList)。
  • 操作规则:insertRule(rule, index)deleteRule(index)
  • 跨浏览器兼容性问题较多,实际项目通常避免直接操作样式表。

3.4 元素尺寸与位置(重要考点)

偏移量(相对于父元素)

  • offsetHeight / offsetWidth:元素在页面中占用的尺寸(包括边框、内边距、滚动条、内容)。
  • offsetTop / offsetLeft:元素相对于 offsetParent 的偏移量。
    • offsetParent:指向包含该元素的最近且具有定位(relative/absolute)的祖先,若无则为 body。

客户端尺寸(不包含边框和滚动条)

  • clientWidth / clientHeight:元素内容区宽度 + 左右内边距,不包括边框和滚动条(但在有滚动条时可能包含滚动条占位,浏览器存在差异)。

滚动尺寸

  • scrollHeight / scrollWidth:元素内容的总高度/宽度(包括溢出的部分)。
  • scrollLeft / scrollTop:元素滚动条滚动的距离(可读写)。

确定元素相对于视口的位置

  • getBoundingClientRect() 方法:返回 DOMRect 对象,包含 lefttoprightbottomwidthheight,这些坐标相对于视口(不含滚动偏移)。
  • 结合 window.pageXOffset / window.pageYOffset 可得到相对于页面的坐标。

4. DOM 遍历(Traversal)

4.1 NodeIterator

  • 用于深度优先遍历 DOM 树。
  • 创建:document.createNodeIterator(root, whatToShow, filter, entityReferenceExpansion)
    • whatToShow:位掩码常量(如 NodeFilter.SHOW_ELEMENTSHOW_TEXT)。
    • filter:可以是过滤器对象(含 acceptNode 方法)或函数。
  • 方法:nextNode()previousNode()

4.2 TreeWalker

  • 比 NodeIterator 更强大,支持在节点间移动(父、子、同胞等)。
  • 创建:document.createTreeWalker() 参数同 createNodeIterator
  • 方法:parentNode()firstChild()lastChild()previousSibling()nextSibling()nextNode()previousNode()
  • 可以使用 filter 过滤节点,并且支持 currentNode 属性重置当前位置。

5. DOM 范围(Range)

5.1 创建与使用

  • 创建范围:document.createRange()
  • 设置边界:
    • selectNode(node):选中整个节点。
    • selectNodeContents(node):选中节点的内容(不含节点本身)。
    • setStart(refNode, offset)setEnd(refNode, offset):精细控制边界。
  • 操作范围:
    • deleteContents():删除范围内容。
    • extractContents():提取范围内容(返回文档片段)。
    • cloneContents():克隆范围内容。
    • insertNode(node):在范围起点插入节点。
    • surroundContents(node):用给定节点包裹范围内容。

5.2 折叠与比较

  • collapse(toStart):折叠范围到起点或终点。
  • compareBoundaryPoints(how, sourceRange):比较两个范围的边界。

5.3 应用场景

  • 富文本编辑器(contenteditable)中实现加粗、斜体等格式化。
  • 跨浏览器选择文本和操作 DOM 结构。

6. 小结

  • DOM2 模块多:核心、视图、事件、样式、遍历范围。
  • 样式操作:style 对象管内联,getComputedStyle 算最终。
  • 尺寸偏移:offset 占位大小,client 内容可视,scroll 滚动总尺寸。
  • 遍历工具:NodeIterator 简单走,TreeWalker 灵活移。
  • 范围选择:createRange 选内容,delete/extract 都可。

7. 常见面试题速查

  1. offsetWidthclientWidthscrollWidth 的区别?
    offsetWidth = 内容 + 内边距 + 边框 + 滚动条(如果有);clientWidth = 内容 + 内边距(不含边框和滚动条);scrollWidth = 内容总宽(含溢出未显示的部分)。

  2. 如何获取元素相对于视口的位置?
    element.getBoundingClientRect() 返回相对于视口的 topleft 等坐标。

  3. getComputedStyle 的作用是什么?
    → 获取元素最终计算后的样式(只读),包括外部样式表和浏览器默认样式。

  4. NodeIteratorTreeWalker 有什么区别?
    TreeWalker 继承自 NodeIterator,增加了在节点间移动(父、子、同胞)的方法,使用更灵活。

  5. DOM 中如何深克隆一个外部文档的节点到当前文档?
    document.importNode(node, true)

  6. compareDocumentPosition 方法返回什么?
    → 返回表示两节点位置关系的位掩码(如 0x01 为不在同一文档,0x02 为在前,0x04 为在后,0x08 为包含,0x10 为被包含)。

  7. 如何操作样式表中的规则?
    → 通过 document.styleSheets 获取 CSSStyleSheet 对象,然后使用 insertRuledeleteRule 方法。

  8. createRange 创建的 Range 可以做什么?
    → 可选择、删除、复制、插入 DOM 中的一段内容,常用于富文本编辑器。

posted @ 2024-04-28 16:01  Li_pk  阅读(6)  评论(0)    收藏  举报