You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JS中如何正确克隆<template>内容,解决获取firstChild为文本节点的问题

问题原因

模板标签内的换行、缩进空格会被浏览器解析为文本节点,你调用cloneNode(true)后拿到的文档片段的第一个子节点是<li>标签前的空白文本节点,自然不存在id、innerText这类元素属性,和克隆操作本身无关。

可直接落地的解决方案

方案1:使用选择器定位元素(最稳妥,不受模板格式影响)

直接通过标签名/类名从克隆的文档片段中匹配目标元素,不用依赖节点顺序,修改代码如下:

createTaskHtml(content, status, id){
    const template = document.getElementById("li-temp").content.cloneNode(true);
    // 用querySelector直接定位元素,避免文本节点干扰
    const li = template.querySelector('li');
    const deleteButton = template.querySelector('.delete-item-button');
    li.id = id;
    li.innerText = content;
    if (status === "done"){
        li.classList.add("todo-item__done");
        deleteButton.classList.remove("delete-item-button-not-displayed");
        this.setListener(deleteButton);
    }
    // 注意:原代码仅返回li会丢失按钮,你可以直接返回整个克隆的文档片段,或者把按钮插入到li内部再返回li
    return template;
}

方案2:移除模板内的空白字符

把模板内容的换行、缩进全部删掉,避免生成文本节点,修改模板代码如下:

<template id="li-temp"><li class="todo-item__undone"></li><button class="delete-item-button delete-item-button-not-displayed">&#10008;</button></template>

修改后原有firstChild、lastChild的逻辑可以正常运行,但后续修改模板内容时如果再次加入换行缩进会重新触发问题,稳定性不如方案1。

方案3:过滤文本节点

遍历克隆后的节点列表,只保留元素节点:

const elements = [...template.childNodes].filter(node => node.nodeType === Node.ELEMENT_NODE);
const li = elements[0];
const deleteButton = elements[1];

内容的提问来源于stack exchange,提问作者Vadim Vedenin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 09:15:00