JavaScript修改DOM元素內(nèi)容的方法大全
1. 引言:為什么需要?jiǎng)討B(tài)修改DOM內(nèi)容?
在現(xiàn)代Web應(yīng)用中,靜態(tài)頁(yè)面已經(jīng)遠(yuǎn)遠(yuǎn)不能滿足用戶需求。從簡(jiǎn)單的文本更新到復(fù)雜的動(dòng)態(tài)界面,都需要我們能夠高效、安全地修改DOM元素內(nèi)容。掌握DOM內(nèi)容修改技術(shù),是實(shí)現(xiàn)以下功能的基礎(chǔ):
- 用戶交互反饋(如表單提交后的提示信息)
- 動(dòng)態(tài)數(shù)據(jù)展示(如實(shí)時(shí)數(shù)據(jù)儀表盤(pán))
- 單頁(yè)面應(yīng)用(SPA)的視圖更新
- 內(nèi)容懶加載和無(wú)限滾動(dòng)
2. 基礎(chǔ)方法:三大內(nèi)容屬性對(duì)比
2.1 innerHTML:功能強(qiáng)大但需謹(jǐn)慎使用
innerHTML是最常用的內(nèi)容修改屬性,它可以獲取或設(shè)置元素的HTML內(nèi)容。
// 獲取元素內(nèi)容
const content = document.getElementById('container').innerHTML;
// 設(shè)置元素內(nèi)容
document.getElementById('container').innerHTML = '<h2>新標(biāo)題</h2><p>段落內(nèi)容</p>';
優(yōu)點(diǎn):
- 可以解析HTML標(biāo)簽
- 使用簡(jiǎn)單直接
缺點(diǎn):
- 存在XSS安全風(fēng)險(xiǎn)
- 性能相對(duì)較低(尤其是大量操作時(shí))
- 會(huì)破壞現(xiàn)有的事件監(jiān)聽(tīng)器
2.2 textContent:純文本操作的安全選擇
textContent用于獲取或設(shè)置元素的文本內(nèi)容,不會(huì)解析HTML標(biāo)簽。
// 獲取文本內(nèi)容
const text = document.getElementById('title').textContent;
// 設(shè)置文本內(nèi)容
document.getElementById('title').textContent = '新的標(biāo)題文本';
優(yōu)點(diǎn):
- 自動(dòng)轉(zhuǎn)義HTML標(biāo)簽,防止XSS攻擊
- 性能優(yōu)于innerHTML
缺點(diǎn):
- 不能解析HTML標(biāo)簽
2.3 innerText:感知樣式的文本操作
innerText與textContent類(lèi)似,但會(huì)考慮CSS樣式,不顯示隱藏元素的文本。
// 獲取可見(jiàn)文本
const visibleText = document.getElementById('element').innerText;
// 設(shè)置文本
document.getElementById('element').innerText = '新內(nèi)容';
優(yōu)點(diǎn):
- 考慮元素可見(jiàn)性
- 返回人類(lèi)可讀的格式(會(huì)忽略多余空格和換行)
缺點(diǎn):
- 性能較差(需要計(jì)算樣式)
- 瀏覽器兼容性略有差異
三大屬性對(duì)比表
| 特性 | innerHTML | textContent | innerText |
|---|---|---|---|
| 處理HTML | 是 | 否 | 否 |
| 性能 | 中等 | 高 | 低 |
| 安全性 | 低(XSS風(fēng)險(xiǎn)) | 高 | 高 |
| 考慮CSS樣式 | 否 | 否 | 是 |
| 保留格式 | 是 | 是(包括隱藏內(nèi)容) | 否(人類(lèi)可讀格式) |
3. 高級(jí)內(nèi)容操作技術(shù)
3.1 使用DOM API創(chuàng)建和添加元素
直接操作DOM節(jié)點(diǎn)雖然代碼量較多,但性能更好且更安全。
// 創(chuàng)建新元素
const newDiv = document.createElement('div');
newDiv.className = 'alert';
newDiv.setAttribute('role', 'alert');
// 創(chuàng)建文本節(jié)點(diǎn)
const textNode = document.createTextNode('操作成功!');
// 添加文本到元素
newDiv.appendChild(textNode);
// 添加到DOM中
document.getElementById('container').appendChild(newDiv);
3.2 使用DocumentFragment優(yōu)化批量操作
當(dāng)需要添加多個(gè)元素時(shí),使用DocumentFragment可以顯著提高性能。
// 創(chuàng)建文檔片段
const fragment = document.createDocumentFragment();
// 批量創(chuàng)建元素并添加到片段
for (let i = 0; i < 100; i++) {
const item = document.createElement('li');
item.textContent = `項(xiàng)目 ${i + 1}`;
fragment.appendChild(item);
}
// 一次性添加到DOM
document.getElementById('list').appendChild(fragment);
3.3 使用insertAdjacentHTML進(jìn)行精確插入
insertAdjacentHTML方法可以在指定位置插入HTML字符串,比innerHTML更加靈活。
const element = document.getElementById('target');
// 在元素開(kāi)始前插入
element.insertAdjacentHTML('beforebegin', '<p>在前方插入</p>');
// 在元素第一個(gè)子元素前插入
element.insertAdjacentHTML('afterbegin', '<p>在內(nèi)部開(kāi)頭插入</p>');
// 在最后一個(gè)子元素后插入
element.insertAdjacentHTML('beforeend', '<p>在內(nèi)部末尾插入</p>');
// 在元素結(jié)束后插入
element.insertAdjacentHTML('afterend', '<p>在后方插入</p>');
4. 現(xiàn)代API:更優(yōu)雅的內(nèi)容操作方式
4.1 使用模板元素(Template)
<template>標(biāo)簽提供了一種更聲明式的內(nèi)容操作方式。
<template id="user-card">
<div class="user-card">
<h3 class="user-name"></h3>
<p class="user-email"></p>
</div>
</template>
// 使用模板
const template = document.getElementById('user-card');
const clone = template.content.cloneNode(true);
// 填充數(shù)據(jù)
clone.querySelector('.user-name').textContent = '張三';
clone.querySelector('.user-email').textContent = 'zhangsan@example.com';
// 添加到DOM
document.getElementById('container').appendChild(clone);
4.2 使用DOMParser解析HTML字符串
DOMParser可以將HTML字符串轉(zhuǎn)換為DOM節(jié)點(diǎn),避免XSS風(fēng)險(xiǎn)。
const parser = new DOMParser();
const htmlString = '<div><h2>標(biāo)題</h2><p>內(nèi)容</p></div>';
// 解析HTML
const doc = parser.parseFromString(htmlString, 'text/html');
const nodes = doc.body.childNodes;
// 添加到DOM
document.getElementById('container').appendChild(nodes[0]);
5. 性能優(yōu)化與最佳實(shí)踐
5.1 減少重排和重繪
DOM操作會(huì)觸發(fā)瀏覽器的重排和重繪,影響性能。
// 不佳:多次操作觸發(fā)多次重排
for (let i = 0; i < 100; i++) {
document.getElementById('list').innerHTML += `<li>項(xiàng)目 ${i}</li>`;
}
// 更佳:使用文檔片段減少重排
const fragment = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
const li = document.createElement('li');
li.textContent = `項(xiàng)目 ${i}`;
fragment.appendChild(li);
}
document.getElementById('list').appendChild(fragment);
5.2 使用事件委托避免內(nèi)存泄漏
使用innerHTML會(huì)移除現(xiàn)有元素上的事件監(jiān)聽(tīng)器,事件委托可以解決這個(gè)問(wèn)題。
// 不佳:直接添加事件監(jiān)聽(tīng)器
document.getElementById('container').innerHTML = '<button class="btn">點(diǎn)擊</button>';
document.querySelector('.btn').addEventListener('click', handleClick);
// 更佳:使用事件委托
document.getElementById('container').innerHTML = '<button class="btn">點(diǎn)擊</button>';
document.getElementById('container').addEventListener('click', (event) => {
if (event.target.classList.contains('btn')) {
handleClick();
}
});
5.3 安全考慮:防止XSS攻擊
直接使用innerHTML插入用戶提供的內(nèi)容可能導(dǎo)致XSS攻擊。
// 危險(xiǎn):直接插入用戶輸入
const userInput = '<script>惡意代碼</script>';
document.getElementById('container').innerHTML = userInput;
// 安全:使用textContent或DOMParser
document.getElementById('container').textContent = userInput;
// 或者使用專(zhuān)門(mén)的消毒庫(kù)
// 如DOMPurify.sanitize(userInput)
6. 實(shí)際應(yīng)用場(chǎng)景
6.1 動(dòng)態(tài)表單反饋
function showFormMessage(message, type = 'success') {
const messageDiv = document.createElement('div');
messageDiv.className = `alert alert-${type}`;
messageDiv.textContent = message;
// 插入到表單前面
const form = document.getElementById('myForm');
form.parentNode.insertBefore(messageDiv, form);
// 3秒后自動(dòng)消失
setTimeout(() => {
messageDiv.remove();
}, 3000);
}
6.2 實(shí)時(shí)數(shù)據(jù)更新
function updateDashboard(data) {
// 使用文檔片段批量更新
const fragment = document.createDocumentFragment();
Object.entries(data).forEach(([key, value]) => {
const element = document.createElement('div');
element.className = 'data-item';
element.innerHTML = `
<span class="data-label">${key}:</span>
<span class="data-value">${value}</span>
`;
fragment.appendChild(element);
});
// 清空容器并添加新內(nèi)容
const container = document.getElementById('dashboard');
container.innerHTML = '';
container.appendChild(fragment);
}
6.3 無(wú)限滾動(dòng)列表
let isLoading = false;
window.addEventListener('scroll', () => {
const { scrollTop, scrollHeight, clientHeight } = document.documentElement;
if (scrollTop + clientHeight >= scrollHeight - 100 && !isLoading) {
isLoading = true;
// 顯示加載指示器
document.getElementById('loading').style.display = 'block';
// 加載更多數(shù)據(jù)
loadMoreItems()
.then(items => {
const fragment = document.createDocumentFragment();
items.forEach(item => {
const li = document.createElement('li');
li.textContent = item.title;
fragment.appendChild(li);
});
document.getElementById('list').appendChild(fragment);
})
.finally(() => {
isLoading = false;
document.getElementById('loading').style.display = 'none';
});
}
});
7. 總結(jié)與選擇指南
修改DOM元素內(nèi)容有多種方法,選擇合適的方法取決于具體場(chǎng)景:
- 簡(jiǎn)單文本更新 → 使用
textContent - 需要包含HTML標(biāo)簽 → 使用
innerHTML(注意XSS風(fēng)險(xiǎn))或insertAdjacentHTML - 批量添加多個(gè)元素 → 使用
DocumentFragment - 復(fù)雜模板內(nèi)容 → 使用
<template>標(biāo)簽 - 需要最高安全性 → 使用
textContent或DOMParser
關(guān)鍵要點(diǎn):
- 優(yōu)先考慮安全性,避免XSS漏洞
- 批量操作DOM以減少重排和重繪
- 根據(jù)場(chǎng)景選擇最合適的方法
- 現(xiàn)代API(如Template、DocumentFragment)能提供更好的性能和可維護(hù)性
通過(guò)掌握這些技術(shù)和方法,你將能夠高效、安全地操作DOM內(nèi)容,創(chuàng)建出更加動(dòng)態(tài)和交互性強(qiáng)的Web應(yīng)用。
以上就是JavaScript修改DOM元素內(nèi)容的方法大全的詳細(xì)內(nèi)容,更多關(guān)于JavaScript修改DOM元素內(nèi)容的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
微信小程序?qū)崿F(xiàn)下拉刷新動(dòng)畫(huà)
這篇文章主要為大家詳細(xì)介紹了微信小程序動(dòng)畫(huà)實(shí)現(xiàn)下拉刷新動(dòng)畫(huà),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-06-06
JavaScript代碼執(zhí)行的先后順序問(wèn)題
今天就給大家介紹一個(gè)特別基礎(chǔ)的東西,javascript中函數(shù)的一點(diǎn)兒小知識(shí)之js代碼的執(zhí)行順序問(wèn)題,需要的朋友參考下吧2017-10-10
JavaScript?映射器?array.flatMap()
這篇文章主要介紹了JavaScript?映射器?array.flatMap(),array.flatMap()是一個(gè)映射函數(shù),它接收一個(gè)數(shù)組和一個(gè)映射函數(shù),然后返回一個(gè)新的映射數(shù)組,下面進(jìn)入文章了解具體內(nèi)容2022-02-02
淺談Webpack自動(dòng)化構(gòu)建實(shí)踐指南
本篇文章主要介紹了Webpack自動(dòng)化構(gòu)建實(shí)踐指南,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-12-12
Chrome插件(擴(kuò)展)開(kāi)發(fā)全攻略(完整demo)
Chrome插件是一個(gè)用Web技術(shù)開(kāi)發(fā)、用來(lái)增強(qiáng)瀏覽器功能的軟件,它其實(shí)就是一個(gè)由HTML、CSS、JS、圖片等資源組成的一個(gè).crx后綴的壓縮包,本文給大家分享一個(gè)Chrome插件(擴(kuò)展)開(kāi)發(fā)全攻略完整demo,感興趣的朋友跟隨小編一起學(xué)習(xí)下吧2021-05-05
前端Base64格式文件上傳原理、實(shí)現(xiàn)與最佳實(shí)踐
Base64 上傳是前端處理文件時(shí)的一個(gè)經(jīng)典方案,尤其在接口只支持 JSON、需要同時(shí)傳文件+其他字段、或要做圖片預(yù)覽的場(chǎng)景中非常實(shí)用,因此本文將從原理到代碼,再到生產(chǎn)級(jí)最佳實(shí)踐,一次性講透,需要的朋友可以參考下2026-02-02
JavaScript實(shí)現(xiàn)動(dòng)畫(huà)打開(kāi)半透明提示層的方法
這篇文章主要介紹了JavaScript實(shí)現(xiàn)動(dòng)畫(huà)打開(kāi)半透明提示層的方法,涉及javascript操作DOM的相關(guān)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04

