在 cloneNode

问题描述

我有一个纯 JS 函数,可以根据一大块“模板”HTML 向页面添加消息。

const setMessage = (msg,type,msg_ct) => {
    const msg_text = document.createTextNode(msg)
    const elementTocopy = document.querySelector('#js_message_template')
    const msg_container = document.querySelector('#js_message_container')
    const clone = elementTocopy.cloneNode(true)

    clone.id = `js_message_alert_${msg_ct}`
    clone.classList.add(`alert-${type}`)
    clone.appendChild(msg_text)
    msg_container.appendChild(clone);   
}

VS 代码抱怨 clone.idclone.classList,因为 Node 不能拥有这些属性

现在,我所看到的关于像这样克隆一大块 HTML 的每个答案和教程基本上都说要做我正在做的事情。

我也可以看到这是一个 Typescript 错误,但据我所知,这也支持 VS Code JS 检查,所以目前我认为这是一个有效的错误 (?)

节点没有这样的 ID 是有道理的,但是当我这样做时,设置 ID 并将类添加到该节点的外部元素的正确方法是什么?再次,所有谷歌搜索都会引导我找到完全符合我正在做的事情的示例!

解决方法

您可以通过使用 JSDOC 指定它的类型来修复它,例如:

/** @type {HTMLElement} */
const clone = elementToCopy.cloneNode(true);

更好的方法是instanceof

const clone = elementToCpoy.cloneNode(true);
if (clone instanceof HTMLElement) {
    ...
}
,

我假设您正在克隆一个 HTMLElement(一个 HTMLElement 派生自 Element,它从 Node 驱动)。

节点没有 id 属性,但 HTMLElement(还有 Element)有。

您所要做的就是告诉编译器克隆的节点比 Node 更具体。例如

const clone = elementToCopy.cloneNode(true) as HTMLElement;

如果你真的想要安全,你可以明确地检查它。例如:

const clone = elementToCopy.cloneNode(true)
if (clone instanceof HTMLElement) {
  clone.id = `js_message_alert_${msg_ct}`
  ...
}

由你决定。