ZetCode

JavaScript innerHTML

最后修改于 2025 年 4 月 2 日

在本文中,我们将探讨 JavaScript 中的 innerHTML 属性。此属性对于 DOM 操作至关重要,它允许开发人员获取或设置元素的 HTML 内容。

基本定义

innerHTML 属性获取或设置元素中包含的 HTML 或 XML 标记。它是 JavaScript 中动态内容更新最强大的属性之一。

读取 innerHTML 时,它以字符串形式返回 HTML 内容。设置 innerHTML 时,它会用解析后的 HTML 字符串完全替换元素的内容。

innerHTML 的基本用法

此示例演示了如何使用 innerHTML 获取和设置 HTML 内容。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Basic innerHTML</title>
</head>
<body>

<div id="content"><p>Original content</p></div>
<button onclick="changeContent()">Change Content</button>

<script>
    function changeContent() {
        const element = document.getElementById('content');
        console.log(element.innerHTML); // Logs current content
        
        element.innerHTML = '<h2>New Content</h2><p>Changed via innerHTML</p>';
    }
</script>

</body>
</html>

在这个基本示例中,我们有一个具有初始内容的 div 元素。当点击按钮时,JavaScript 代码首先记录当前的 HTML 内容,然后用新的 HTML 标记替换它。

这演示了 innerHTML 访问和修改元素内容的根本用法。该属性可以处理复杂的 HTML 结构,而不仅仅是纯文本。

创建动态列表

此示例展示了如何使用 innerHTML 动态生成列表项。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Dynamic Lists</title>
</head>
<body>

<ul id="fruitList"></ul>
<button onclick="generateList()">Generate List</button>

<script>
    function generateList() {
        const fruits = ['Apple', 'Banana', 'Orange', 'Mango'];
        const listElement = document.getElementById('fruitList');
        
        let listHTML = '';
        fruits.forEach(fruit => {
            listHTML += `<li>${fruit}</li>`;
        });
        
        listElement.innerHTML = listHTML;
    }
</script>

</body>
</html>

这里我们从一个空的无序列表开始。当点击按钮时,generateList 函数会从数组创建列表项的 HTML,并使用 innerHTML 将它们插入。

这演示了 innerHTML 如何一次性有效地更新多个元素。先构建 HTML 字符串然后一次性设置它,比多次 DOM 操作更具性能优势。

安全注意事项

此示例演示了 innerHTML 潜在的安全风险。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Security Risks</title>
</head>
<body>

<div id="userContent"></div>
<input type="text" id="userInput" placeholder="Enter some text">
<button onclick="displayContent()">Display</button>

<script>
    function displayContent() {
        const input = document.getElementById('userInput').value;
        const element = document.getElementById('userContent');
        
        // UNSAFE: Potential XSS vulnerability
        element.innerHTML = input;
        
        // SAFER alternative:
        // element.textContent = input;
    }
</script>

</body>
</html>

在此示例中,用户输入直接通过 innerHTML 插入页面。如果输入包含恶意脚本标签,这将导致 XSS 漏洞。

在使用 innerHTML 之前,请始终对用户输入进行消毒,或者在只需要纯文本时考虑使用 textContent。这是处理动态内容时一个至关重要的安全注意事项。

性能比较

此示例比较了 innerHTML 和 DOM 操作方法。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Performance Comparison</title>
</head>
<body>

<div id="container1"></div>
<div id="container2"></div>
<button onclick="runTest()">Run Test</button>

<script>
    function runTest() {
        const items = Array(1000).fill().map((_, i) => `Item ${i + 1}`);
        
        // Using innerHTML
        console.time('innerHTML');
        const container1 = document.getElementById('container1');
        container1.innerHTML = items.map(item => `<div>${item}</div>`).join('');
        console.timeEnd('innerHTML');
        
        // Using DOM methods
        console.time('DOM');
        const container2 = document.getElementById('container2');
        items.forEach(item => {
            const div = document.createElement('div');
            div.textContent = item;
            container2.appendChild(div);
        });
        console.timeEnd('DOM');
    }
</script>

</body>
</html>

此代码比较了两种添加 1000 个元素的方法:使用 innerHTML 与使用 DOM 操作方法。控制台计时显示了性能差异。

innerHTML 通常在批量操作方面更快,因为它最大限度地减少了重排和重绘。然而,DOM 方法提供了更多的控制,并且在处理用户生成的内容时更安全。

与模板字面量结合使用

此示例展示了如何将模板字面量与 innerHTML 结合用于复杂的 HTML。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Template Literals</title>
    <style>
        .card {
            border: 1px solid #ccc;
            padding: 10px;
            margin: 10px;
            width: 200px;
        }
    </style>
</head>
<body>

<div id="cardContainer"></div>
<button onclick="createCard()">Add Card</button>

<script>
    function createCard() {
        const container = document.getElementById('cardContainer');
        const title = 'Sample Card';
        const content = 'This card was created using template literals and innerHTML';
        
        container.innerHTML += `
            <div class="card">
                <h3>${title}</h3>
                <p>${content}</p>
                <small>Created: ${new Date().toLocaleTimeString()}</small>
            </div>
        `;
    }
</script>

</body>
</html>

在这里,我们使用模板字面量来创建一种清晰、可读的方式来生成复杂的 HTML 结构。卡片模板包含动态数据,并使用 innerHTML 追加到容器中。

模板字面量通过保持结构可见性,使 HTML 生成更易于维护。请注意使用 += 进行追加而不是替换现有内容。

来源

MDN innerHTML 文档

在本文中,我们展示了如何在 JavaScript 中使用 innerHTML 属性。此强大功能可实现动态内容更新,但需要谨慎使用,特别是在安全性和性能方面。

作者

我叫 Jan Bodnar,我是一名充满激情的程序员,拥有丰富的编程经验。我自 2007 年以来一直在撰写编程文章。迄今为止,我已撰写了 1,400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出 所有 JS DOM 教程