javascript 中复制 dom 节点主要用 clonenode(boolean):true 为深克隆(含子节点、属性、文本,但不复制事件监听器、表单实时值、动态样式);false 为浅克隆(仅节点本身)。

在 JavaScript 中复制 DOM 节点,主要用 cloneNode() 方法。它能创建一个指定节点的副本,但要注意深拷贝与浅拷贝的区别。
基本用法:cloneNode(boolean)
cloneNode() 接收一个布尔值参数:
-
true:深克隆 —— 复制节点及其所有子节点、属性、文本内容,但不复制事件监听器、表单元素的当前值(如<input>的value)、或动态设置的 DOM 属性(如element.style.color = 'red'); -
false:浅克隆 —— 只复制节点本身(如一个<div> 标签),不包含任何子节点。 <h3>常见操作示例</h3> <p>假设有一个 DOM 元素:</p> <font color="#666"><pre class="brush:php;toolbar:false;"><div id="origin"> <p>Hello</p><div class="aritcle_card flexRow artxards"> <div class="artcardd flexRow"> <a class="aritcle_card_img" rel="nofollow" href="/xiazai/gongju/2847" title="OpenJDK 24"><img src="https://img.php.cn/upload/manual/001/431/639/6acf4227f079d889.png" alt="OpenJDK 24" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a> <div class="aritcle_card_info flexColumn"> <a rel="nofollow" href="/xiazai/gongju/2847" title="OpenJDK 24" class="overflowclass">OpenJDK 24</a> <p class="overflowclass">OpenJDK 24 Windows x64 官方参考实现(24+36),适合 Windows 环境进行 Java 开发、编译、运行和版本兼容性验证。</p> </div> <a rel="nofollow" href="/xiazai/gongju/2847" title="OpenJDK 24" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div> <span>World</span> </div></pre></font> <p>复制并插入到页面中:</p> <ul> <li>深克隆:<code>const clone = document.getElementById('origin').cloneNode(true); - 添加到父容器:
document.body.appendChild(clone); - 注意:克隆后的节点 ID 不再唯一,若原节点有
id="origin",克隆体也带相同 ID,需手动修改(如clone.id = "origin-clone")以避免冲突。
克隆后需要手动处理的内容
cloneNode() 不会自动继承以下内容:
- 绑定的事件监听器(
addEventListener添加的); - 表单控件的实时值(
<input value="user input">的输入内容不会被克隆,只保留 HTML 中的value属性值); - 通过 JS 设置的属性(如
elem.dataset.foo = 'bar'或elem.className = 'active')一般会被保留(因为属于属性/特性范畴),但部分动态状态(如checked、selected)取决于浏览器实现,稳妥做法是克隆后显式同步; - 自定义属性或框架绑定的数据(如 Vue/React 的响应式数据)完全不会被复制。
替代方案:outerHTML + createElement(仅适用于简单场景)
对纯静态结构,也可用字符串方式重建:
const html = origin.outerHTML;const temp = document.createElement('div');temp.innerHTML = html;const clone = temp.firstElementChild;
⚠️ 注意:这种方式会丢失所有事件监听、JS 属性状态,且可能触发脚本执行(如果含 <script></script>),不推荐用于复杂或安全敏感场景。










