JavaScript高级程序设计笔记 14

第14章 DOM(文档对象模型)

1. DOM 概述

  • DOM 是 HTML/XML 文档的编程接口,将文档表示为节点树。
  • 级别:DOM Level 1(核心+HTML)、Level 2(样式、事件、遍历)、Level 3(加载与保存、验证)。

2. 节点层级

2.1 Node 类型(基类)

  • 所有节点类型均继承自 Node
  • 常用常量:Node.ELEMENT_NODE(1)、TEXT_NODE(3)、DOCUMENT_NODE(9)。
  • 节点属性:
    • nodeNamenodeValue(元素节点无意义,文本节点存文本)。
    • parentNodechildNodesNodeList,类数组且动态实时)、firstChildlastChildpreviousSiblingnextSibling
    • ownerDocument(指向所属文档)。
  • 节点方法:
    • appendChild()insertBefore()replaceChild()removeChild()(均需父节点调用)。
    • cloneNode(deep)(深克隆包含子节点)。
    • normalize()(合并相邻文本节点)。

2.2 Document 类型

  • document 对象(浏览器中为 HTMLDocument 实例),表示整个文档。
  • 属性:documentElement<html>)、body<body>)、titleURLdomainreferrer
  • 获取元素:
    • getElementById(id)(最常用,ID 必须唯一)。
    • getElementsByTagName(tag)(返回动态 HTMLCollection)。
    • getElementsByName(name)
    • querySelector(selector) / querySelectorAll(selector)(返回静态 NodeList,推荐)。
  • 特殊集合:anchorsformsimageslinks 等。
  • 写入文档:write()writeln()(尽量少用,会阻塞解析)。

2.3 Element 类型

  • 表示 HTML/XML 元素。
  • 属性:
    • idclassNameclassList(方便操作类名)。
    • attributes(NamedNodeMap,元素的属性集合)。
  • 方法:
    • 获取/设置属性:getAttribute()setAttribute()removeAttribute()
    • 属性访问:直接用 .property 访问标准属性(如 div.id),自定义属性用 getAttributedataset
  • dataset:访问 data-* 属性(如 element.dataset.userId 对应 data-user-id)。
  • 创建元素:document.createElement(tagName)

2.4 Text 类型

  • 表示文本节点,nodeValuedata 存储文本。
  • 方法:appendData()deleteData()insertData()replaceData()splitText()
  • 创建文本节点:document.createTextNode(text)

2.5 Comment 类型(注释节点)

  • nodeType === 8,可用 document.createComment(text) 创建。

2.6 CDATASection、DocumentType 等(较少用)

3. DOM 操作

3.1 创建与插入节点

let div = document.createElement('div');
div.className = 'box';
div.innerHTML = '<span>Hello</span>';
document.body.appendChild(div);

3.2 删除与替换

parent.removeChild(child);
parent.replaceChild(newNode, oldNode);

3.3 性能优化(减少重排/重绘)

  • 使用 document.createDocumentFragment() 批量添加节点。
  • 先操作脱离文档的节点,最后一次性插入。
  • 避免频繁读取布局属性(如 offsetHeight)。

4. 选择符 API

  • querySelector(selector):返回第一个匹配的元素(无则 null)。
  • querySelectorAll(selector):返回静态 NodeList(快照)。
  • matches(selector):检测元素是否匹配选择符(element.matchesmsMatchesSelector)。

5. 元素遍历(Element Traversal API)

  • 只遍历元素节点,忽略文本/注释节点:
    • parentElementchildren(HTMLCollection)、firstElementChildlastElementChildpreviousElementSiblingnextElementSibling

6. HTML5 新增 DOM 扩展

6.1 类名操作

  • classListadd()remove()toggle()contains()(极大便利)。

6.2 焦点管理

  • document.activeElement:当前获得焦点的元素。
  • element.focus()element.blur()

6.3 自定义数据属性

  • dataset 对象,如 <div data-id="123">div.dataset.id === '123'

6.4 插入标记

  • innerHTML / outerHTML / insertAdjacentHTML(position, html)
  • innerHTML 性能与安全问题:避免直接拼接用户输入(XSS)。

6.5 scrollIntoView()

  • 滚动元素到可视区域:element.scrollIntoView({ behavior: 'smooth' })

7. 样式与类

7.1 内联样式

  • element.style.property(驼峰命名,如 backgroundColor)。
  • element.style.cssText 批量设置。

7.2 计算样式

  • getComputedStyle(element, pseudo):返回只读对象,包含最终样式。

8. 节点遍历(TreeWalker / NodeIterator)

  • document.createNodeIterator(root, whatToShow, filter):遍历节点。
  • document.createTreeWalker:增加移动方法(parentNodefirstChild 等)。

9. 常见面试题速查

  1. DOM 节点类型有哪几种?如何判断?
    → 元素(1)、属性(2)、文本(3)、文档(9)、注释(8) 等;通过 nodeType

  2. querySelectorAll 返回的是动态还是静态集合?
    → 静态 NodeList(快照),不随 DOM 变化更新。

  3. getElementsByTagNamequerySelectorAll 的区别?
    → 前者返回动态 HTMLCollection,后者返回静态 NodeList;后者支持任意 CSS 选择符。

  4. 如何创建文档片段?有何作用?
    createDocumentFragment(),用于批量操作节点,避免多次重绘。

  5. innerHTML 的安全风险?如何防范?
    → 可能注入 XSS;应对用户输入进行转义或使用 textContent 替代。

  6. classList 相比 className 的优势?
    → 提供 addremovetoggle 等方便操作,不会覆盖已有类。

  7. 如何获取元素的最终样式?
    getComputedStyle(element)

  8. scrollIntoView 的常用参数?
    { behavior: 'smooth', block: 'start' } 等。

  9. childNodeschildren 的区别?
    childNodes 包含所有节点(文本、注释等),children 只包含元素节点。

  10. 如何遍历 DOM 树?
    → 递归 children 或使用 TreeWalker

posted @ 2024-04-25 09:14  Li_pk  阅读(8)  评论(0)    收藏  举报