lesson68:JavaScript 操作 HTML 元素、属性与样式全指南

目录

[一、HTML 元素操作:从选择到操控](#一、HTML 元素操作:从选择到操控)

[1. 元素选择:精准定位 DOM 节点](#1. 元素选择:精准定位 DOM 节点)

[2. 元素创建与插入:动态构建页面](#2. 元素创建与插入:动态构建页面)

[3. 元素删除与替换:清理 DOM 结构](#3. 元素删除与替换:清理 DOM 结构)

二、属性操作:控制元素特性

[1. 标准属性操作](#1. 标准属性操作)

直接属性访问(推荐)

[setAttribute/getAttribute 方法](#setAttribute/getAttribute 方法)

[2. 自定义数据属性(Data Attributes)](#2. 自定义数据属性(Data Attributes))

三、样式操作:动态视觉效果

[1. 内联样式操作](#1. 内联样式操作)

[2. 类样式操作(推荐)](#2. 类样式操作(推荐))

[3. 计算样式获取](#3. 计算样式获取)

[四、事件驱动的 DOM 操作实践](#四、事件驱动的 DOM 操作实践)

[示例:待办事项列表(Todo List)](#示例:待办事项列表(Todo List))

五、性能优化策略

[1. 减少 DOM 操作次数](#1. 减少 DOM 操作次数)

[2. 避免重排与重绘](#2. 避免重排与重绘)

[3. 事件优化](#3. 事件优化)

六、总结与扩展学习


在现代前端开发中,JavaScript 与 DOM(文档对象模型)的交互是实现动态网页的核心。无论是用户交互、数据渲染还是样式调整,都离不开对 HTML 元素、属性及样式的精准操作。本文将系统梳理 JavaScript 操作 DOM 的核心方法与最佳实践,帮助开发者高效掌握动态网页开发技能。

一、HTML 元素操作:从选择到操控

1. 元素选择:精准定位 DOM 节点

获取 DOM 元素是一切操作的前提,JavaScript 提供了多种选择方法,适用于不同场景:

方法 语法示例 返回值 特点
getElementById document.getElementById('header') 单个元素 基于 ID 查找,效率最高
querySelector document.querySelector('.nav > li:first-child') 单个元素 支持 CSS 选择器,灵活性强
getElementsByClassName document.getElementsByClassName('item') HTMLCollection 返回动态集合,实时更新
getElementsByTagName document.getElementsByTagName('div') HTMLCollection 按标签名查找,返回动态集合
querySelectorAll document.querySelectorAll('ul li') NodeList 支持 CSS 选择器,返回静态集合

关键区别

  • HTMLCollection 是动态集合 (DOM 变化时自动更新),NodeList 通常是静态集合(快照式返回)
  • querySelectorAll 支持复杂选择器(如 :nth-child、属性选择器),但返回结果不实时更新
  • 推荐优先使用 querySelectorquerySelectorAll,兼顾简洁性与灵活性

2. 元素创建与插入:动态构建页面

通过 JavaScript 动态生成 DOM 元素是实现交互功能的基础:

javascript 复制代码
// 创建元素
const newDiv = document.createElement('div');
newDiv.textContent = '动态创建的元素';


// 添加属性
newDiv.id = 'dynamic-div';
newDiv.className = 'content-section';


// 插入页面
const container = document.querySelector('.container');
container.appendChild(newDiv); // 添加到容器末尾


// 插入到指定位置(在目标元素前)
const target = document.querySelector('#target');
container.insertBefore(newDiv, target);


// 创建文本节点(更细粒度控制)
const textNode = document.createTextNode('仅文本内容');
newDiv.appendChild(textNode);

文档片段优化

批量插入元素时使用 DocumentFragment 减少 DOM 重绘:

javascript 复制代码
const fragment = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
const li = document.createElement('li');
li.textContent = `列表项 ${i}`;
fragment.appendChild(li);
}
document.querySelector('ul').appendChild(fragment); // 仅触发一次重绘

3. 元素删除与替换:清理 DOM 结构

javascript 复制代码
// 删除元素
const toRemove = document.querySelector('#old-element');
toRemove.parentNode.removeChild(toRemove);


// 替换元素
const newElement = document.createElement('p');
newElement.textContent = '替换内容';
const oldElement = document.querySelector('#replace-me');
oldElement.parentNode.replaceChild(newElement, oldElement);

注意 :删除元素前需确保其父节点存在,避免抛出 Cannot read property 'removeChild' of null 错误。

二、属性操作:控制元素特性

1. 标准属性操作

HTML 元素的标准属性(如 srchrefclass)可通过两种方式操作:

直接属性访问(推荐)
javascript 复制代码
const img = document.querySelector('img');
img.src = 'new-image.jpg'; // 设置属性
console.log(img.alt); // 获取属性
img.disabled = true; // 布尔属性(表单元素)
setAttribute/getAttribute 方法
javascript 复制代码
const link = document.querySelector('a');
link.setAttribute('target', '_blank'); // 设置自定义或非标准属性
console.log(link.getAttribute('data-id')); // 获取属性值
link.removeAttribute('title'); // 删除属性

区别

  • 直接属性访问返回标准化值 (如 input.value 返回当前输入值)
  • getAttribute 返回HTML 原始值 (如 input.getAttribute('value') 返回初始值)
  • 布尔属性(如 disabled)通过直接属性访问更直观(element.disabled = true

2. 自定义数据属性(Data Attributes)

HTML5 引入的 data-* 属性是存储自定义数据的标准方式,通过 dataset API 操作:

html 复制代码
<div id="user" data-user-id="123" data-user-name="John"></div>
javascript 复制代码
const user = document.querySelector('#user');
console.log(user.dataset.userId); // "123"(自动转换为驼峰命名)
console.log(user.dataset.userName); // "John"


// 设置自定义属性
user.dataset.userAge = '30';
// 移除属性
delete user.dataset.userName;

优势

  • 数据与元素紧密关联,语义清晰
  • 自动支持 CSS 选择器(如 [data-user-id="123"]
  • 避免污染全局命名空间

三、样式操作:动态视觉效果

1. 内联样式操作

通过 element.style 访问内联样式(驼峰命名法):

javascript 复制代码
const box = document.querySelector('.box');
box.style.width = '200px';
box.style.backgroundColor = '#f0f0f0'; // 对应 CSS 的 background-color
box.style.fontSize = '16px';


// 清除样式
box.style.removeProperty('width');

注意

  • style 属性仅能获取/设置内联样式 ,无法读取外部 CSS 或 <style> 标签定义的样式
  • 复合属性需拆分(如 border 需分别设置 borderWidthborderColor 等)

2. 类样式操作(推荐)

通过 classList API 操作 CSS 类,实现样式与逻辑分离:

javascript 复制代码
const element = document.querySelector('.card');
element.classList.add('active', 'highlight'); // 添加多个类
element.classList.remove('disabled'); // 移除类
element.classList.toggle('hidden'); // 切换类(存在则移除,不存在则添加)
console.log(element.classList.contains('active')); // 检查类是否存在(返回布尔值)

优势

  • 避免内联样式的优先级问题
  • 便于维护(样式集中在 CSS 文件)
  • 支持批量操作多个类名

3. 计算样式获取

通过 getComputedStyle 获取元素最终渲染的样式(包含所有 CSS 规则计算结果):

javascript 复制代码
const element = document.querySelector('.content');
const computedStyle = getComputedStyle(element);
console.log(computedStyle.fontSize); // "16px"(计算后的值)
console.log(computedStyle.color); // "rgb(51, 51, 51)"(标准化为 RGB 格式)

特点

  • 返回值为只读,无法通过此方法修改样式
  • 包含继承的样式(如 colorfont-size
  • 单位统一转换(如 em 转为 px

四、事件驱动的 DOM 操作实践

动态网页的核心是响应用户交互,以下是事件处理与 DOM 操作结合的典型场景:

示例:待办事项列表(Todo List)

html 复制代码
<input type="text" id="todo-input" placeholder="输入待办事项">
<button id="add-btn">添加</button>
<ul id="todo-list"></ul>
javascript 复制代码
const input = document.querySelector('#todo-input');
const addBtn = document.querySelector('#add-btn');
const list = document.querySelector('#todo-list');


// 添加待办项
addBtn.addEventListener('click', () => {
const text = input.value.trim();
if (!text) return;


const li = document.createElement('li');
li.innerHTML = `
<span>${text}</span>
<button class="delete-btn">删除</button>
`;
list.appendChild(li);
input.value = ''; // 清空输入框
});


// 删除待办项(事件委托)
list.addEventListener('click', (e) => {
if (e.target.classList.contains('delete-btn')) {
e.target.parentNode.remove();
}
});

核心技巧

  • 使用事件委托(将事件绑定到父元素)处理动态生成元素的事件
  • 避免频繁操作 DOM,通过 innerHTML 批量更新或使用文档片段
  • 操作后清理资源(如清空输入框、移除事件监听器)

五、性能优化策略

DOM 操作是前端性能瓶颈之一,以下方法可显著提升性能:

1. 减少 DOM 操作次数

  • 批量处理 :先构建离线 DOM 树(如 DocumentFragment),再一次性插入文档
  • 样式集中修改 :通过添加/移除类名而非逐个修改 style 属性

2. 避免重排与重绘

  • 读写分离:避免在循环中交替读取和修改 DOM 样式(如先读取所有 offsetHeight 再统一修改)
  • 使用 CSS containment :对频繁变化的元素设置 contain: layout paint; 隔离重排范围
  • 隐藏元素操作 :先将元素设为 display: none,修改完成后恢复显示

3. 事件优化

  • 使用事件委托减少事件监听器数量
  • 及时移除不再需要的事件监听器(尤其是单页应用中)

六、总结与扩展学习

JavaScript DOM 操作是前端开发的基石,掌握本文介绍的元素选择、属性控制、样式修改及事件处理方法,可满足大部分动态网页开发需求。核心要点:

  • 选择元素 :优先使用 querySelector/querySelectorAll,兼顾灵活性与性能
  • 操作属性 :标准属性用直接访问,自定义数据用 data-* + dataset
  • 控制样式 :优先操作 classList,避免内联样式,计算样式用 getComputedStyle
  • 性能优化:减少 DOM 操作、避免重排重绘、使用事件委托

扩展学习资源

通过持续实践与优化,你将能构建出交互流畅、性能优异的现代网页应用。

相关推荐
妄小闲2 小时前
html网站源码 html网页模板下载
前端·html
小二·2 小时前
前端笔记:HTML output标签介绍及用法
javascript·笔记·html5
熊猫_豆豆2 小时前
MATLAB画出湖面波纹相遇所形成的现象
开发语言·matlab·仿真
宁雨桥2 小时前
前端登录加密实战:从原理到落地,守护用户密码安全
前端·安全·状态模式
椒盐螺丝钉3 小时前
TypeScript类型兼容性
运维·前端·typescript
_JinHao3 小时前
Cesium Viewer对象详解——Cesium基础笔记(快速入门)
前端·javascript·笔记·3d·webgl
花心蝴蝶.3 小时前
Java 中的代理模式
java·开发语言·代理模式
正义的大古3 小时前
OpenLayers地图交互 -- 章节十三:拖拽旋转交互详解
javascript·vue.js·openlayers