阿里云主机折上折
  • 微信号
Current Site:Index > The DOM tree structure

The DOM tree structure

Author:Chuan Chen 阅读数:64986人阅读 分类: JavaScript

Basic Concepts of DOM Tree Structure

The DOM (Document Object Model) tree is the in-memory representation of an HTML document. When a browser loads an HTML page, it parses the HTML code and constructs a tree-like structure composed of nodes. This tree reflects the hierarchical relationships in the HTML document, where each HTML element, attribute, and text content becomes a node in the tree.

<!DOCTYPE html>
<html>
<head>
    <title>Sample Page</title>
</head>
<body>
    <h1>Main Heading</h1>
    <p>Paragraph Text</p>
</body>
</html>

The DOM tree structure for the simple HTML document above is as follows:

document
├── html
    ├── head
    │   └── title
    │       └── "Sample Page"
    └── body
        ├── h1
        │   └── "Main Heading"
        └── p
            └── "Paragraph Text"

Types of DOM Nodes

The DOM tree consists of different types of nodes, each with specific properties and methods:

  1. Document Node: The root node of the entire document
  2. Element Node: Nodes corresponding to HTML tags
  3. Attribute Node: Attributes of HTML elements
  4. Text Node: Text content within elements
  5. Comment Node: HTML comments
// Examples of accessing different node types
const docNode = document; // Document node
const elementNode = document.body; // Element node
const attrNode = elementNode.attributes[0]; // Attribute node
const textNode = elementNode.firstChild; // Text node
const commentNode = document.createComment('This is a comment'); // Comment node

DOM Tree Traversal Methods

Traversing the DOM tree is a common task in front-end development. Here are several commonly used traversal methods:

Parent-Child Relationship Traversal

// Get parent node
const parent = element.parentNode;

// Get all child nodes (including text nodes, etc.)
const children = element.childNodes;

// Get first child node
const firstChild = element.firstChild;

// Get last child node
const lastChild = element.lastChild;

Sibling Relationship Traversal

// Get previous sibling node
const prevSibling = element.previousSibling;

// Get next sibling node
const nextSibling = element.nextSibling;

Using querySelector Methods

// Get the first matching element
const firstMatch = document.querySelector('.className');

// Get all matching elements
const allMatches = document.querySelectorAll('div');

DOM Tree Modification Operations

In addition to traversal, we often need to modify the DOM tree structure:

Creating New Nodes

// Create new element
const newDiv = document.createElement('div');

// Create text node
const newText = document.createTextNode('New text content');

// Create attribute node
const newAttr = document.createAttribute('data-custom');
newAttr.value = 'value';

Adding Nodes

// Append child node
parentElement.appendChild(newChild);

// Insert before a specified node
parentElement.insertBefore(newNode, referenceNode);

// Replace child node
parentElement.replaceChild(newChild, oldChild);

Removing Nodes

// Remove child node
parentElement.removeChild(childNode);

// Modern method (no need to know parent node)
element.remove();

DOM Tree Performance Optimization

Frequent DOM operations can impact page performance. Here are some optimization suggestions:

Using Document Fragments

const fragment = document.createDocumentFragment();

for (let i = 0; i < 100; i++) {
    const div = document.createElement('div');
    div.textContent = `Item ${i}`;
    fragment.appendChild(div);
}

document.body.appendChild(fragment);

Batch Style Modifications

// Bad practice
element.style.color = 'red';
element.style.backgroundColor = 'blue';
element.style.fontSize = '14px';

// Good practice
element.style.cssText = 'color: red; background-color: blue; font-size: 14px;';

// Better practice
element.className = 'active'; // Use CSS classes

Event Delegation

// Bad practice
document.querySelectorAll('li').forEach(li => {
    li.addEventListener('click', handleClick);
});

// Good practice (event delegation)
document.querySelector('ul').addEventListener('click', function(e) {
    if (e.target.tagName === 'LI') {
        handleClick(e);
    }
});

Concept of Virtual DOM

Modern front-end frameworks like React and Vue use Virtual DOM technology to improve performance:

// Simplified Virtual DOM example
const virtualDom = {
    type: 'div',
    props: {
        className: 'container',
        children: [
            {
                type: 'h1',
                props: {
                    children: 'Hello World'
                }
            },
            {
                type: 'p',
                props: {
                    children: 'This is a paragraph'
                }
            }
        ]
    }
};

// Render Virtual DOM to real DOM
function render(vnode) {
    if (typeof vnode === 'string') {
        return document.createTextNode(vnode);
    }
    
    const node = document.createElement(vnode.type);
    
    if (vnode.props) {
        Object.keys(vnode.props).forEach(prop => {
            if (prop !== 'children') {
                node.setAttribute(prop, vnode.props[prop]);
            }
        });
        
        if (vnode.props.children) {
            vnode.props.children.forEach(child => {
                node.appendChild(render(child));
            });
        }
    }
    
    return node;
}

document.body.appendChild(render(virtualDom));

DOM Tree Access Control

For security reasons, browsers impose some restrictions on DOM access:

Same-Origin Policy

// Cross-domain iframe access will be blocked
try {
    const iframe = document.getElementById('foreign-iframe');
    const iframeDoc = iframe.contentDocument; // Security error
} catch (e) {
    console.error('Same-origin policy blocked access:', e);
}

Shadow DOM

Web components use Shadow DOM to encapsulate internal structures:

class MyComponent extends HTMLElement {
    constructor() {
        super();
        const shadow = this.attachShadow({mode: 'open'});
        shadow.innerHTML = `
            <style>
                p { color: red; }
            </style>
            <p>Shadow DOM content</p>
        `;
    }
}

customElements.define('my-component', MyComponent);

DOM Tree Debugging Techniques

Browser developer tools provide powerful DOM debugging features:

  1. Element Inspection: Right-click on a page element and select "Inspect"
  2. DOM Breakpoints: Set subtree modification breakpoints on elements
  3. Console Access: $0 references the currently selected element
  4. Monitoring Property Changes: Object.getOwnPropertyDescriptor(element, 'property')
// Debugging DOM in the console
const el = document.querySelector('div');
// Monitoring property changes
Object.defineProperty(el, 'hidden', {
    set: function(value) {
        debugger; // Trigger debugger
        this.setAttribute('hidden', value);
    }
});

DOM Tree Compatibility Issues

Different browsers implement DOM differently, so be aware of:

Event Handling Differences

// Standardized event handling
function addEvent(element, type, handler) {
    if (element.addEventListener) {
        element.addEventListener(type, handler, false);
    } else if (element.attachEvent) {
        element.attachEvent('on' + type, handler);
    } else {
        element['on' + type] = handler;
    }
}

Style Retrieval Differences

// Get computed styles
function getStyle(element, property) {
    if (window.getComputedStyle) {
        return window.getComputedStyle(element)[property];
    } else {
        return element.currentStyle[property]; // IE
    }
}

Modern DOM APIs

Browsers continue to add new DOM APIs to simplify operations:

MutationObserver

// Monitor DOM changes
const observer = new MutationObserver(mutations => {
    mutations.forEach(mutation => {
        console.log('DOM changed:', mutation.type);
    });
});

observer.observe(document.body, {
    childList: true,
    attributes: true,
    subtree: true
});

IntersectionObserver

// Monitor element visibility
const io = new IntersectionObserver(entries => {
    entries.forEach(entry => {
        if (entry.isIntersecting) {
            console.log('Element entered viewport:', entry.target);
        }
    });
});

document.querySelectorAll('.lazy-load').forEach(el => {
    io.observe(el);
});

Extended Applications of DOM Trees

The concept of DOM trees can be extended to other domains:

XML Document Processing

const xmlString = `<books>
    <book>
        <title>Professional JavaScript</title>
        <author>Nicholas C. Zakas</author>
    </book>
</books>`;

const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlString, "text/xml");
const titles = xmlDoc.getElementsByTagName('title');
console.log(titles[0].textContent); // "Professional JavaScript"

SVG Manipulation

const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.setAttribute("width", "100");
svg.setAttribute("height", "100");

const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
circle.setAttribute("cx", "50");
circle.setAttribute("cy", "50");
circle.setAttribute("r", "40");
circle.setAttribute("fill", "red");

svg.appendChild(circle);
document.body.appendChild(svg);

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

上一篇:类数组对象

下一篇:节点类型与属性

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.