欢迎光临
我们一直在努力

DOM 元素内容与属性操作

2.2 DOM 元素内容与属性操作

元素内容与属性操作是 DOM 视图动态更新的核心手段,通过 JavaScript 可以实时修改页面的文本内容、HTML 结构与标签属性,实现数据渲染、状态切换、交互反馈等核心交互效果。

不同的内容操作方式在安全性、性能、语义上存在显著差异,理解其边界与适用场景,是规避 XSS 风险、性能损耗与兼容性问题的基础。


2.2.1 内容读写操作(innerHTML/innerText/textContent)

JavaScript 提供了三种常用的元素内容读写属性,分别面向 HTML 结构、可见文本、全量文本三种场景,三者在读取范围、写入行为、安全性能上差异明显。

一、innerHTML

innerHTML 用于读写元素内部的完整 HTML 代码。读取时返回元素内所有 HTML 标记字符串;

写入时会将字符串作为 HTML 解析,生成新的 DOM 节点替换原有内容。

const box = document.querySelector('.box');

// 读取 HTML 结构

console.log(box.innerHTML);

// 写入 HTML 结构,浏览器会自动解析标签生成 DOM

box.innerHTML = '<p>这是一段<strong>加粗</strong>文本</p>';

  • 核心特点:
    • 支持渲染完整 HTML 结构,是富文本、模板渲染的核心方式
    • 写入时会销毁原有子节点及其事件绑定,完整重建 DOM 子树
    • 高安全风险:直接插入未过滤的用户输入会导致 XSS 攻击
    • 性能开销大:大量 HTML 写入会触发完整的解析、重排与重绘
二、innerText

innerText 用于读写元素的可见文本内容,返回结果与用户肉眼在页面上看到的文本一致,受 CSS 样式影响。

const box = document.querySelector('.box');

console.log(box.innerText); // 仅返回页面可见的文本

box.innerText = '<p>纯文本</p>'; // 会作为纯文本显示,不会解析标签

  • 核心特点:
    • 写入时作为纯文本处理,不会解析 HTML 标签,天然防御 XSS
    • 读取时会触发 CSS 样式计算(重排),性能较差
    • 自动忽略 display: none 的隐藏元素、<script>/<style> 内的文本
    • 会保留换行与基本排版格式,输出更贴近视觉效果
三、textContent

textContent 用于读写元素内的全部文本内容,包含所有子节点的文本,不考虑 CSS 样式与元素可见性。

const box = document.querySelector('.box');

console.log(box.textContent); // 返回所有文本,包括隐藏元素的内容

box.textContent = '纯文本内容'; // 纯文本写入,不解析标签

  • 核心特点:
    • 写入时纯文本处理,无 XSS 安全风险
    • 读取时不触发样式计算,性能远优于 innerText
    • 会获取所有文本节点,包括隐藏元素、注释外的所有文本内容
    • 不会自动处理排版格式,仅保留原始文本的换行符
四、三者对比与选型

对比维度

innerHTML

innerText

textContent

读取内容

完整 HTML 代码,包含标签

仅可见文本,受 CSS 影响

全部文本内容,含隐藏文本

写入行为

解析 HTML 标签,重建 DOM

纯文本渲染,不解析标签

纯文本渲染,不解析标签

安全性

存在 XSS 注入风险

安全,无 XSS 风险

安全,无 XSS 风险

性能表现

差,触发完整解析与重排

较差,读取触发样式重排

好,仅操作文本节点

适用场景

可信 HTML 结构渲染

需要匹配视觉可见文本的场景

纯文本读写、性能优先场景

五、最佳实践
  • 纯文本更新优先使用 textContent,性能最优且安全
  • 仅在渲染可信 HTML 内容时使用 innerHTML,用户输入内容必须先做 XSS 过滤
  • 避免频繁调用 innerHTML 做小幅修改,优先操作具体节点的属性与文本
  • 大量内容渲染避免字符串拼接式 innerHTML,推荐使用 DocumentFragment 批量操作

2.2.2 原生属性与自定义属性操作

HTML 元素的属性分为原生标准属性(如 id、class、src)和自定义属性两类,JavaScript 提供了两套操作方式:DOM 对象属性直接访问、Attribute 系列方法,二者在行为上存在关键差异。

一、DOM 对象属性直接访问(点语法)

通过 element.属性名 直接读写 DOM 对象的属性,仅支持原生标准属性,操作的是内存中 DOM 对象的属性值,而非 HTML 标签上的原始值。

const input = document.querySelector('input');

// 读取原生属性

console.log(input.id);

console.log(input.value);

// 修改原生属性

input.className = 'active';

input.disabled = true;

  • 核心特点:
    • 仅支持标准原生属性,无法直接操作非标准自定义属性
    • 返回值是经过浏览器处理的当前状态值,而非标签原始字符串
      • 例如 img.src 返回完整绝对路径,而非标签上的相对路径
      • 布尔属性(disabled、checked)返回真正的布尔值 true/false
    • 直接操作内存对象,读写性能更高
二、Attribute 系列方法

通过 getAttribute()、setAttribute()、removeAttribute()、hasAttribute() 方法操作 HTML 标签上的属性,支持所有属性包括自定义属性,操作的是标签上的原始字符串值。

const link = document.querySelector('a');

// 获取属性值,返回标签上的原始值

console.log(link.getAttribute('href')); // 返回相对路径字符串

// 设置属性

link.setAttribute('target', '_blank');

// 判断属性是否存在

console.log(link.hasAttribute('title'));

// 删除属性

link.removeAttribute('custom-attr');

  • 核心特点:
    • 支持所有属性,包括非标准自定义属性
    • 返回值始终是字符串或 null,布尔属性返回属性名本身或 null
    • 操作会直接修改 HTML 标签结构,变化可反映在 outerHTML 中
    • 性能略低于 DOM 对象直接属性访问
三、核心差异对比

对比项

DOM 对象属性(点语法)

Attribute 系列方法

支持范围

仅原生标准属性

所有属性,含自定义属性

返回值类型

对应属性的实际类型(布尔、数字等)

始终为字符串 /null

值内容

浏览器计算后的当前值(如绝对路径)

标签上的原始字符串值

布尔属性

返回 true /false 布尔值

返回属性名 /null

读写性能

高,直接操作内存

略低,操作标签结构

四、常见坑点
  • class 属性特殊处理:DOM 对象中对应 className,而非 class,因为 class 是 JavaScript 保留字。
  • 布尔属性赋值:setAttribute('disabled', false) 依然会生效,因为布尔属性只要存在即为真,移除需用 removeAttribute()。
  • value 属性差异:input.value 是用户输入的实时值,getAttribute('value') 是标签上的初始默认值。

  • 2.2.3 data-* 数据集规范

    data-* 是 HTML5 标准化的自定义属性方案,通过统一的 data- 前缀定义自定义属性,既符合标准规范,又避免与未来原生属性冲突,同时配套了专属的 dataset API,是元素关联业务数据的推荐方式。

    一、基础语法与命名规则
    • 在 HTML 标签中以 data- 为前缀,后面跟自定义属性名,多单词命名使用横杠分隔
    • DOM 中对应 dataset 属性,是一个 DOMStringMap 对象,自动将横杠命名转换为驼峰命名

    示例:

    <!– HTML 中定义 data-* 属性 –>

    <li data-id="1001" data-user-name="张三" data-status="active">列表项</li>

    const li = document.querySelector('li');

    // 通过 dataset 读取,横杠自动转为驼峰

    console.log(li.dataset.id); // "1001"

    console.log(li.dataset.userName); // "张三"

    // 设置属性,同步更新 HTML 标签

    li.dataset.status = 'disabled';

    // 删除属性

    delete li.dataset.status;

    二、核心特点
  • 标准合规:W3C 官方标准方案,不会与原生属性冲突,兼容所有现代浏览器
  • 双向同步:修改 dataset 会同步更新 HTML 标签属性,修改标签属性也会同步到 dataset
  • 字符串限制:所有值都会被转为字符串存储,数字、布尔值等读取后需要手动转换类型
  • 语义化:明确标识为自定义数据属性,提升 HTML 源码可读性
  • 三、典型应用场景
  • 列表项数据绑定:给列表元素绑定业务 ID、状态等数据,事件委托中直接读取
  • const list = document.querySelector('.list');

    list.addEventListener('click', (e) => {

      const item = e.target.closest('li');

      if (item) {

        const id = item.dataset.id;

        console.log('点击了项:', id);

      }

    });

  • 状态标记:标记元素的交互状态(如展开 / 收起、加载中),配合 CSS 属性选择器控制样式
  • 配置传递:在 DOM 标签上预置组件配置参数,组件初始化时统一读取
  • 四、注意事项
    • 仅适合存储少量简单数据,大量复杂数据建议使用 Map 与元素关联存储
    • 所有值均为字符串类型,读取后需根据业务做显式类型转换
    • 避免存储敏感信息,data-* 属性会直接暴露在 HTML 源码中
    • 严格遵循横杠转驼峰命名规则,不要在 dataset 中使用大写字母直接命名
    赞(0)
    未经允许不得转载:171主机测评 » DOM 元素内容与属性操作
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址