DOM 与 BOM

DOM 与 BOM 详解

DOM (文档对象模型)

定义:将 HTML/XML 文档解析为树形结构的编程接口,允许 JavaScript 操作页面内容

核心结构

graph TD A[Document] --> B[Element: html] B --> C[Element: head] B --> D[Element: body] C --> E[Element: title] C --> F[Element: meta] D --> G[Element: div] D --> H[Element: p] D --> I[Element: script] G --> J[Text: Hello] H --> K[Text: World]

关键节点类型

类型 说明 示例
Document 整个文档的入口 document
Element HTML 标签元素 <div>, <p>
Attr 元素属性 class="container"
Text 文本节点 Hello World
Comment 注释节点 <!-- comment -->

常用 API

// 查询元素
document.getElementById('header')
document.querySelector('.btn')

// 修改内容
element.textContent = 'New text'
element.innerHTML = '<span>Content</span>'

// 操作样式
element.style.color = 'red'
element.classList.add('active')

// 事件处理
button.addEventListener('click', handleClick)

BOM (浏览器对象模型)

定义:提供与浏览器窗口交互的 API,无正式标准但被浏览器广泛支持

核心对象

graph LR W[window] --> N[navigator] W --> L[location] W --> H[history] W --> S[screen] W --> C[console] W --> X[XMLHttpRequest] W --> T[setTimeout]

主要对象功能

对象 用途 示例
window 浏览器窗口的顶级对象 window.innerWidth
navigator 浏览器信息 navigator.userAgent
location URL操作和页面导航 location.href
history 浏览历史记录管理 history.back()
screen 用户屏幕信息 screen.width
console 调试输出 console.log()
localStorage 本地存储 localStorage.setItem()

常用 API

// 导航控制
location.assign('https://example.com')
history.pushState({}, '', '/new-page')

// 窗口操作
window.open('popup.html')
window.resizeTo(800, 600)

// 定时器
const timer = setTimeout(() => {}, 1000)
const interval = setInterval(() => {}, 2000)

// 存储数据
localStorage.setItem('theme', 'dark')
const theme = localStorage.getItem('theme')

DOM vs BOM 对比

特性 DOM BOM
标准 W3C 正式标准 无官方标准(浏览器实现)
作用对象 文档内容 浏览器窗口/环境
核心对象 Document, Element, Node Window, Navigator, Location
主要用途 操作页面元素 控制浏览器行为
操作示例 修改文本/样式/结构 导航/弹窗/存储/定时器
依赖关系 依赖 BOM 的 window.document 独立存在

关键交互场景

  1. DOM 操作触发 BOM 行为

    // 点击按钮跳转页面 (DOM事件 → BOM操作)
    document.getElementById('btn').addEventListener('click', () => {
      location.href = '/next-page'; // BOM
    });
    
  2. BOM 事件影响 DOM

    // 窗口大小变化时修改布局 (BOM事件 → DOM操作)
    window.addEventListener('resize', () => {
      const width = window.innerWidth; // BOM
      document.body.style.padding = width > 768 ? '2rem' : '1rem'; // DOM
    });
    
  3. 联合使用示例

    // 保存表单数据到本地存储
    document.querySelector('form').addEventListener('submit', (e) => {
      e.preventDefault();
      const data = new FormData(e.target); // DOM
      localStorage.setItem('formData', JSON.stringify(data)); // BOM
      history.back(); // BOM
    });
    

性能优化建议

  1. DOM 操作优化

    // 批量修改(减少重排)
    const fragment = document.createDocumentFragment();
    for (let i = 0; i < 100; i++) {
      const div = document.createElement('div');
      fragment.appendChild(div);
    }
    document.body.appendChild(fragment);
    
    // 读写分离(避免布局抖动)
    const width = element.offsetWidth; // 先读
    element.style.width = width + 10 + 'px'; // 后写
    
  2. BOM 使用注意事项

    // 避免同步BOM操作阻塞主线程
    // 错误示范
    const data = localStorage.getItem('bigData'); // 同步读取大文件
    
    // 正确做法
    setTimeout(() => {
      const data = localStorage.getItem('bigData');
    }, 0);
    
  3. 现代 API 替代方案

    // 使用 requestAnimationFrame 替代 setTimeout
    function animate() {
      element.style.left = (pos += 5) + 'px';
      if (pos < 100) requestAnimationFrame(animate);
    }
    requestAnimationFrame(animate);
    

黄金法则
DOM 操作是前端性能瓶颈主要来源,每次重排(Reflow)都会触发计算开销。
应减少直接 DOM 操作次数,优先使用 documentFragment、虚拟 DOM 等优化手段。
BOM 操作注意同步 API 的阻塞风险(如 localStorage 大文件读取)。

posted @ 2025-06-27 15:12  张浩伟  阅读(24)  评论(0)    收藏  举报