7、JavaScript DOM 和 BOM 详解

12 阅读3分钟

1. 什么是DOM

DOM概述

DOM(Document Object Model),即文档对象模型,是HTML和XML文档的编程接口。它提供了一种结构化表示文档的方法,并定义了如何通过脚本访问和操作文档的内容。

常见DOM方法

查询元素

  • getElementById(id) - 通过元素的ID获取元素
  • getElementsByClassName(className) - 通过类名获取元素集合
  • getElementsByTagName(tagName) - 通过标签名获取元素集合
  • querySelector(selector) - 通过CSS选择器获取第一个匹配的元素
  • querySelectorAll(selector) - 通过CSS选择器获取所有匹配的元素集合

创建和删除元素

  • createElement(tagName) - 创建元素
  • appendChild(child) - 添加子元素
  • removeChild(child) - 删除子元素
  • replaceChild(newChild, oldChild) - 替换子元素

修改元素属性

  • setAttribute(name, value) - 设置属性
  • getAttribute(name) - 获取属性
  • removeAttribute(name) - 移除属性

修改元素样式和内容

  • innerHTML - 设置或获取元素的HTML内容
  • textContent - 设置或获取元素的文本内容
  • style - 设置或获取元素的样式

示例代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>DOM示例</title>
</head>
<body>
    <div id="app">
        <h1 class="title">Hello, World!</h1>
    </div>
    <script>
        // 获取元素
        const app = document.getElementById('app');
        const title = document.querySelector('.title');
        
        // 创建新元素
        const newParagraph = document.createElement('p');
        newParagraph.textContent = 'This is a new paragraph.';

        // 添加新元素到DOM
        app.appendChild(newParagraph);

        // 修改元素内容
        title.innerHTML = 'New Title';

        // 修改元素属性
        newParagraph.setAttribute('class', 'new-class');

        // 修改元素样式
        newParagraph.style.color = 'blue';

        // 删除元素
        app.removeChild(title);
    </script>
</body>
</html>

2. 什么是BOM

BOM概述

BOM(Browser Object Model),即浏览器对象模型,是指由浏览器提供的用于操作浏览器窗口和其文档的接口。BOM使我们能够与浏览器进行交互,控制它的行为和属性。

常见BOM方法

window对象

  • alert(message) - 显示警告框
  • confirm(message) - 显示确认框
  • prompt(message, default) - 显示提示框,获取用户输入
  • open(url, target) - 打开新窗口
  • close() - 关闭当前窗口

navigator对象

  • navigator.userAgent - 获取浏览器的用户代理字符串
  • navigator.platform - 获取操作系统信息
  • navigator.language - 获取浏览器的语言设定

location对象

  • location.href - 获取或设置当前URL
  • location.reload() - 重新加载当前页面
  • location.assign(url) - 加载新的URL
  • location.replace(url) - 用新的URL替换当前URL,不保存历史记录

history对象

  • history.back() - 浏览器回退
  • history.forward() - 浏览器前进
  • history.go(n) - 导航到历史记录中的某一页

示例代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>BOM示例</title>
</head>
<body>
    <button onclick="showAlert()">Show Alert</button>
    <button onclick="showConfirm()">Show Confirm</button>
    <button onclick="showPrompt()">Show Prompt</button>
    <button onclick="navigate()">Navigate</button>
    <button onclick="window.history.back()">Go Back</button>
    <button onclick="window.history.forward()">Go Forward</button>

    <script>
        function showAlert() {
            window.alert('This is an alert!');
        }

        function showConfirm() {
            const result = window.confirm('Do you confirm?');
            console.log(result);
        }

        function showPrompt() {
            const userInput = window.prompt('Please enter something:');
            console.log(userInput);
        }

        function navigate() {
            window.location.href = 'https://www.example.com';
        }

        // 获取浏览器信息
        console.log('User Agent:', navigator.userAgent);
        console.log('Platform:', navigator.platform);
        console.log('Language:', navigator.language);

        // 重新加载页面
        // window.location.reload();
        
        // 历史记录导航
        // window.history.go(-1); // 回退一页
    </script>
</body>
</html>

3. 深入DOM

动态样式

  • classList.add(className) - 添加类
  • classList.remove(className) - 移除类
  • classList.toggle(className) - 切换类
  • classList.contains(className) - 检查类是否存在
const element = document.querySelector('.example');
element.classList.add('new-class');
element.classList.remove('old-class');

事件处理

  • addEventListener - 添加事件监听器
  • removeEventListener - 移除事件监听器
const button = document.getElementById('myButton');

function handleClick(event) {
    console.log('Button clicked!', event);
}

button.addEventListener('click', handleClick);

// 移除事件监听器
// button.removeEventListener('click', handleClick);

动态插入HTML

  • insertAdjacentHTML - 插入HTML内容
const container = document.getElementById('container');
container.insertAdjacentHTML('beforeend', '<p>New HTML content</p>');

复杂选择器

  • closest(selector) - 获取匹配选择器的最近祖先元素
const element = document.querySelector('.inner');
const nearestDiv = element.closest('div');

4. 深入BOM

window对象

  • window.setTimeout - 设置超时
  • window.setInterval - 设置定时
  • window.clearTimeout - 清除超时
  • window.clearInterval - 清除定时
const timeoutId = window.setTimeout(() => {
    console.log('Timeout executed');
}, 1000);

window.clearTimeout(timeoutId);

const intervalId = window.setInterval(() => {
    console.log('Interval executed');
}, 1000);

window.clearInterval(intervalId);

navigator对象

  • navigator.geolocation - 获取地理位置
navigator.geolocation.getCurrentPosition(position => {
    console.log('Latitude:', position.coords.latitude);
    console.log('Longitude:', position.coords.longitude);
});

location对象

  • location.origin - 获取来源URL
  • location.pathname - 获取路径名
console.log('Origin:', location.origin);
console.log('Pathname:', location.pathname);

history对象

  • history.pushState(state, title, url) - 添加历史记录
  • history.replaceState(state, title, url) - 替换历史记录
history.pushState({ page: 1 }, 'Title', '/page1');
history.replaceState({ page: 2 }, 'Title', '/page2');

高级技巧和最佳实践

  1. 使用DocumentFragment提高性能

    const fragment = document.createDocumentFragment();
    
    for (let i = 0; i < 10; i++) {
        const div = document.createElement('div');
        div.textContent = `Item ${i}`;
        fragment.appendChild(div);
    }
    
    document.body.appendChild(fragment);
    
  2. 使用事件委托优化事件处理

    document.body.addEventListener('click', event => {
        if (event.target.matches('.clickable')) {
            console.log('Clickable item clicked:', event.target);
        }
    });
    
  3. 异步加载脚本

    <script src="script.js" async></script>
    <script src="script.js" defer></script>
    
  4. 使用localStoragesessionStorage进行数据存储

    // localStorage
    localStorage.setItem('key', 'value');
    console.log(localStorage.getItem('key'));
    
    // sessionStorage
    sessionStorage.setItem('key', 'value');
    console.log(sessionStorage.getItem('key'));
    
  5. 使用fetch进行异步请求

    fetch('https://api.example.com/data')
        .then(response => response.json())
        .then(data => console.log(data))
        .catch(error => console.error('Error:', error));