ZetCode

JavaScript cloneNode

最后修改于 2025 年 4 月 2 日

在本文中,我们将探讨 JavaScript 中的 cloneNode 方法。此方法对于 DOM 操作至关重要,它允许开发人员创建现有 DOM 元素的副本。

基本定义

cloneNode 方法会创建一个 DOM 元素的副本。它接受一个布尔参数,该参数决定是否克隆所有子节点。

当传入 true 时,它会执行深度克隆,包括所有子节点。当传入 false 时,它只克隆元素本身,不包括子节点。默认值为 false

基本 cloneNode 示例

此示例演示了如何克隆一个简单的 div 元素并将其追加。

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

<div id="original">Original Element</div>
<button onclick="cloneElement()">Clone Element</button>

<script>
    function cloneElement() {
        const original = document.getElementById('original');
        const clone = original.cloneNode(true);
        document.body.appendChild(clone);
    }
</script>

</body>
</html>

在这个基本示例中,我们有一个 ID 为“original”的 div 元素。JavaScript 代码使用 cloneNode(true) 克隆此元素,并将克隆体追加到文档 body 中。

这演示了 cloneNode 复制元素的根本用法。true 参数确保所有子节点都被克隆。

浅克隆与深克隆

此示例显示了浅克隆与深克隆之间的区别。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Shallow vs Deep</title>
</head>
<body>

<div id="parent">
    Parent Element
    <div>Child Element</div>
</div>
<button onclick="cloneShallow()">Shallow Clone</button>
<button onclick="cloneDeep()">Deep Clone</button>

<script>
    function cloneShallow() {
        const parent = document.getElementById('parent');
        const clone = parent.cloneNode(false);
        document.body.appendChild(clone);
    }
    
    function cloneDeep() {
        const parent = document.getElementById('parent');
        const clone = parent.cloneNode(true);
        document.body.appendChild(clone);
    }
</script>

</body>
</html>

这里我们有一个带有子元素的父元素。cloneShallow 函数执行浅克隆,而 cloneDeep 执行深克隆。

浅克隆(false)只复制父元素而不复制其子节点。深克隆(true)同时复制父元素及其所有子节点。

克隆带事件监听器的元素

此示例演示了事件监听器在克隆元素时的行为。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Cloning Events</title>
</head>
<body>

<button id="originalBtn">Original Button</button>
<button onclick="cloneButton()">Clone Button</button>
<div id="output"></div>

<script>
    const originalBtn = document.getElementById('originalBtn');
    originalBtn.addEventListener('click', function() {
        document.getElementById('output').textContent = 
            'Original button clicked!';
    });
    
    function cloneButton() {
        const clone = originalBtn.cloneNode(true);
        document.body.appendChild(clone);
    }
</script>

</body>
</html>

在此示例中,我们有一个带事件监听器的按钮,以及另一个克隆它的按钮。克隆的按钮将不具有原始按钮的事件监听器。

这表明 cloneNode 只克隆 DOM 结构和属性。使用 addEventListener 添加的事件监听器不会被复制到克隆元素。

克隆表单元素

此示例显示了如何克隆表单元素同时保留其值。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Cloning Forms</title>
</head>
<body>

<form id="originalForm">
    <input type="text" value="Initial value">
    <input type="checkbox" checked>
</form>
<button onclick="cloneForm()">Clone Form</button>

<script>
    function cloneForm() {
        const form = document.getElementById('originalForm');
        const clone = form.cloneNode(true);
        document.body.appendChild(clone);
    }
</script>

</body>
</html>

这里我们有一个包含文本输入框和复选框的表单。cloneForm 函数克隆整个表单,包括其当前状态。

这表明 cloneNode 在克隆表单元素时会保留其当前值和状态。克隆的表单将保留原始表单的所有属性值。

克隆自定义属性

此示例显示了克隆过程中如何处理自定义数据属性。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Custom Attributes</title>
</head>
<body>

<div id="customDiv" data-info="important data">Element with custom data</div>
<button onclick="cloneCustom()">Clone Custom</button>

<script>
    function cloneCustom() {
        const div = document.getElementById('customDiv');
        const clone = div.cloneNode(true);
        
        // Modify the clone's data attribute
        clone.dataset.info = 'cloned data';
        
        document.body.appendChild(clone);
        
        // Log both elements' data attributes
        console.log('Original:', div.dataset.info);
        console.log('Clone:', clone.dataset.info);
    }
</script>

</body>
</html>

在此示例中,我们克隆一个带自定义数据属性的元素,然后修改克隆体的属性。两个元素的属性都会被记录到控制台。

这表明 cloneNode 会复制所有属性,包括自定义数据属性。克隆的元素与原始元素完全独立,允许修改而不影响源元素。

来源

MDN cloneNode 文档

在本文中,我们展示了如何在 JavaScript 中使用 cloneNode 方法。此方法功能强大,可以创建 DOM 元素的副本,同时保持其结构和属性。

作者

我叫 Jan Bodnar,是一名充满激情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。至今,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出 所有 JS DOM 教程