Skip to content

Document Object Model (DOM)

**DOM(文档对象模型)**是一个由浏览器提供的接口,允许开发者使用脚本语言(如 JavaScript)动态地访问和操作 HTML 或 XML 文档的结构、内容和样式。它将文档表示为一个树形结构,其中每个节点都是文档的一部分,如元素、属性、文本、注释等。

DOM 将 HTML 或 XML 文档的每个部分表示为一个对象,允许开发者通过 JavaScript 来修改文档内容、结构和样式,从而使页面动态、交互式。

DOM 结构概述

DOM 树是一个以 document 对象为根的树形结构。文档的每个元素、文本、属性都被表示为树中的节点。DOM 树的常见节点类型包括:

  1. 文档节点(Document):文档的根节点,代表整个 HTML 或 XML 文档。
  2. 元素节点(Element):HTML 标签(如 <div><p><a> 等)在 DOM 中是元素节点。
  3. 文本节点(Text):包含在 HTML 标签中的文本内容。
  4. 属性节点(Attribute):元素的属性(如 id="example", class="myClass" 等)。
  5. 注释节点(Comment):HTML 或 XML 中的注释部分(如 <!-- This is a comment -->)。

DOM 树示意图

               document
                   |
           +----------------+
           |                |
        <html>              Text
           |
       +-------+
       |       |
     <head>   <body>
       |        |
     <title>  <div>
                |
              Text

常用的 DOM 方法和属性

1. 获取 DOM 元素

  1. getElementById():根据元素的 id 获取单个元素。

    javascript
    const element = document.getElementById('myElement');
  2. getElementsByClassName():根据元素的类名获取所有匹配的元素,返回一个“实时”HTML集合。

    javascript
    const elements = document.getElementsByClassName('myClass');
  3. getElementsByTagName():根据标签名获取所有匹配的元素,返回一个“实时”HTML集合。

    javascript
    const divs = document.getElementsByTagName('div');
  4. querySelector():返回匹配 CSS 选择器的第一个元素。

    javascript
    const element = document.querySelector('.myClass');
  5. querySelectorAll():返回所有匹配 CSS 选择器的元素,返回一个静态的 NodeList。

    javascript
    const elements = document.querySelectorAll('.myClass');

2. 修改 DOM 元素

  1. innerHTML:获取或设置元素的 HTML 内容。

    javascript
    const element = document.getElementById('myElement');
    element.innerHTML = '<p>New content</p>';
  2. textContent:获取或设置元素的文本内容。

    javascript
    const element = document.getElementById('myElement');
    element.textContent = 'Hello, world!';
  3. setAttribute():设置元素的属性。

    javascript
    const link = document.getElementById('myLink');
    link.setAttribute('href', 'https://example.com');
  4. getAttribute():获取元素的属性值。

    javascript
    const href = link.getAttribute('href');
  5. style:修改元素的内联样式。

    javascript
    const element = document.getElementById('myElement');
    element.style.color = 'red';

3. 创建和删除节点

  1. createElement():创建一个新的 HTML 元素。

    javascript
    const newDiv = document.createElement('div');
  2. createTextNode():创建一个新的文本节点。

    javascript
    const newText = document.createTextNode('Hello, world!');
  3. appendChild():将新节点添加到父节点的子节点列表中。

    javascript
    const parent = document.getElementById('parent');
    parent.appendChild(newDiv);
  4. removeChild():删除子节点。

    javascript
    const parent = document.getElementById('parent');
    parent.removeChild(newDiv);

4. 访问父节点、子节点和兄弟节点

  1. parentNode:获取父节点。

    javascript
    const parent = element.parentNode;
  2. children:获取所有子元素节点。

    javascript
    const children = element.children;
  3. firstChild / lastChild:获取第一个/最后一个子节点。

    javascript
    const firstChild = element.firstChild;
    const lastChild = element.lastChild;
  4. previousSibling / nextSibling:获取前一个/下一个兄弟节点。

    javascript
    const previous = element.previousSibling;
    const next = element.nextSibling;

事件处理

DOM 允许你为元素添加事件监听器来响应用户的交互,例如点击、鼠标悬停、键盘输入等。

  1. addEventListener():为元素添加事件监听器。

    javascript
    const button = document.getElementById('myButton');
    button.addEventListener('click', function() {
        alert('Button clicked!');
    });
  2. removeEventListener():移除事件监听器。

    javascript
    button.removeEventListener('click', function() {
        alert('Button clicked!');
    });
  3. 事件对象:事件处理函数通常会接收一个事件对象,其中包含事件的详细信息,例如触发事件的元素、鼠标位置、按下的键等。

    javascript
    button.addEventListener('click', function(event) {
        console.log('Event type:', event.type);
        console.log('Clicked element:', event.target);
    });

DOM 性能优化

  1. 减少 DOM 更新的频率:频繁地操作 DOM 会导致性能问题,因为每次 DOM 更新都可能会触发页面的重排(reflow)和重绘(repaint)。尽量批量修改 DOM 以减少重排。

  2. 使用 documentFragment:当插入大量元素时,使用 documentFragment 先将元素添加到内存中,最后一次性插入到 DOM 中,避免多次重排。

    javascript
    const fragment = document.createDocumentFragment();
    const newDiv = document.createElement('div');
    fragment.appendChild(newDiv);
    document.body.appendChild(fragment);
  3. 避免强制同步样式计算:避免在修改 DOM 后立即读取样式属性(如 offsetHeightclientWidth),这样会强制浏览器进行同步计算,降低性能。


总结

DOM 是浏览器提供的一个非常强大的 API,它使得网页可以动态地更新和响应用户的操作。掌握 DOM 操作是成为前端开发者的基础,它允许你控制页面的内容、结构、样式及交互行为。

如果你有更深入的疑问,或者需要更详细的示例,请随时告诉我!