【问题标题】:Node.cloneNode() inconsistent with DOM SpecNode.cloneNode() 与 DOM 规范不一致
【发布时间】:2015-01-27 09:17:23
【问题描述】:

有据可查(主要是在 SO 上)在 <input type="text"> 上使用 Node.cloneNode(true) 会返回一个新的 <input> 节点,其文本内容与原始节点相同,但克隆了一个 <select>(在用户拥有selected) 返回一个新的<select>,而不需要用户选择。起初这似乎不符合规范,因为根据DOM 3

cloneNode
返回此节点的副本,即用作节点的通用复制构造函数。重复节点没有父节点(parentNode 为空)并且没有用户数据。 与导入节点关联的用户数据不会被转移。

为什么会发生这种情况的答案稍后会有所说明,但在DOM 2 spec中更清楚,

cloneNode
克隆元素会复制所有属性及其值,包括由 XML 处理器生成以表示默认属性的属性,但此方法不会复制它包含的任何文本,除非它是深度克隆,因为文本包含在子项中文本节点。

考虑到这种措辞,我愿意接受这种行为,尽管我认为<input> 不包含文本节点,因为<input>childNodes 属性将始终为空@ 987654334@,不管它是否包含文本(在规范的措辞中,“有一个文本节点”)。

至少,我知道用户选择的<option> 被视为用户数据,因此不克隆是有道理的。在这种情况下,这个“用户数据”包含在<option>selected 属性中。

但是,当trying the behavior with radio buttons and checkboxes 时,Chrome 38、FF 33、Safari 6.2 中的行为完全违背了上述定义。克隆选中的复选框或选定的单选按钮会保持它们的选中状态。这似乎与规范相反,因为此信息是“用户数据”,它(如 <select>)包含在属性中(在本例中为 checked)。

我是否正确,这不符合规范?如果没有,是否在其他地方定义了这种行为?如果是的话,是否有一个用例可以解释为什么cloneNode() 在克隆用户输入字段的状态方面如此不一致?


编辑:在针对我的浏览器套件进行测试时,我发现 Opera 12.15 的性能与 <select> 输入一样。也就是说,它保留了克隆时的用户选择。

【问题讨论】:

    标签: javascript html dom clone


    【解决方案1】:

    DOM Level 4 更清楚地定义了cloning steps

    Specifications 可以为全部或部分定义克隆步骤 nodes。该算法通过 copynodedocument 和 可选克隆子标记,如clone 中所示 算法。

    克隆一个节点,可以选择使用一个文档和一个克隆子节点 标记,运行以下步骤:

    1. 如果没有给出document,则令documentnodenode document

    2. copynode,实现与 node 相同的接口。

    3. 如果 copydocument,请将其 node documentdocument 设置为 copy
      否则,将 copynode document 设置为 document

    4. 根据node的类型,将以下内容从node复制到copy

    5. 运行为other applicable specifications 中的node 定义的任何cloning steps,并传递copynodedocument 和 克隆 子标志如果设置,作为参数。

    6. 如果设置了clone children 标志,则clone node 的所有children 并将它们附加到copy , document 为 指定并设置了克隆子标志

    7. 返回副本。

    cloneNode(deep) 方法必须返回 context objectclone,如果 deep 为真,则设置 clone children 标志

    selectinput 都是 Elements,因此只有它们的 namespacenamespace prefixlocal name 及其 attribute list 应在第 4 步中复制。

    但是,在第 5 步中,可能会运行其他克隆步骤。 可能这些步骤包括复制valueselected 属性以防input 元素。

    【讨论】:

    • 我同意这使它更清楚,但是“在其他适用规范中为 node 定义的克隆步骤”似乎含糊不清(而且它似乎没有链接到任何地方)。还有哪些其他规范可以在这里应用?此外,这(或它)如何解释为什么在所有浏览器上,复选框和单选按钮的状态都被克隆(尽管该状态不在“命名空间、命名空间前缀、本地名称或属性列表中)?
    • 是的,它很模糊。我只想指出 DOM L4 可能允许这种行为。
    猜你喜欢
    • 1970-01-01
    • 2021-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-13
    • 2018-06-06
    相关资源
    最近更新 更多