【问题标题】:How to correctly use innerHTML to create an element (with possible children) from a html string?如何正确使用 innerHTML 从 html 字符串创建元素(可能有子元素)?
【发布时间】:2011-04-09 10:26:35
【问题描述】:

注意:我确实想使用任何框架。


目标只是创建一个函数,该函数将基于 HTML 字符串返回一个元素。


假设一个简单的 HTML 文档如下:

<html>
<head></head>
<body>
</body>
</html>

所有提到的函数都包含在 head 部分中,所有 DOM 创建/操作都在脚本标签中的主体末尾完成。


我有一个函数 createElement,它将格式良好的 HTML 字符串作为参数。它是这样的:

function createElement(str)
{
  var div = document.createElement('div');
  div.innerHTML = str;
  return div.childNodes;
}

现在,当您像这样调用它时,这个函数效果很好:

var e = createElement('<p id="myId" class="myClass">myInnerHTML</p>');

由于创建的元素不是“真正的”元素这一小问题(可能是巨大的),它仍然有一个“div”的父节点。如果有人知道如何解决这个问题,那就太棒了。


现在,如果我用更复杂的字符串调用相同的函数:

var e = createElement('<p id="myId" class="myClass">innerHTML<h2 id="h2ID" class="h2CLASS">Heading2</h2></p>');

它会创建两个孩子,而不是一个孩子,另一个孩子有另一个孩子。

一旦你做了 div.innerHTML = str. innerHTML 而不是

`<p id="myId" class="myClass">innerHTML    <h2 id="h2ID" class="h2CLASS">Heading2</h2>    </p>`

转向

`<p id="myId" class="myClass">innerHTML</p>        <h2 id="h2ID" class="h2CLASS">Heading2</h2>`


问题:
  1. 我能否在使用 .innerHTML 后以某种方式获取没有父节点的元素?
  2. 我能否(在稍微复杂的字符串的情况下)让我的函数返回一个带有适当子元素的元素,而不是两个元素。 [它实际上返回三个,&lt;p.myClass#myId&gt;&lt;h2.h2CLASS#h2ID&gt;,和另一个&lt;p&gt;]

【问题讨论】:

  • (1) 您可以从容器中删除节点 (removeNode) 或克隆它们 (cloneNode) (2) 不适用于该示例,因为关于如何使用 &lt;p&gt; 的复杂规则标签工作。您的 &lt;h2&gt; 隐式关闭前面的 &lt;p&gt; 标记,因为 &lt;h2&gt; 是块级元素(与其他各种元素一样)。
  • 尖刻地说

    不是有效的 html 字符串 ;)
  • 好吧是的,这是有道理的。 的不要进入

    标签。这解决了这个问题。

  • 您只能使用 removeNode 来删除 CHILDREN。编辑:nvm。一半的浏览器不支持它。奇怪的是只有IE。

标签: javascript string dom innerhtml


【解决方案1】:

这类似于来自palswim 的答案,只是它不需要创建克隆,而是使用while() 循环,始终将节点附加到[0]

function createElement( str ) {
    var frag = document.createDocumentFragment();

    var elem = document.createElement('div');
    elem.innerHTML = str;

    while (elem.childNodes[0]) {
        frag.appendChild(elem.childNodes[0]);
    }
    return frag;
}

【讨论】:

  • 是的,这可能会减少开销。
  • 这相当于另一个,除了你的最后一行应该是 frag.childNodes 因为我想要元素而不是片段。谢谢!这很有帮助。
  • @Sanchit - 很高兴它有帮助。 :o) 我在返回值上来回走动。认为返回片段将提供更多可能性,因为它可以让您在需要时立即附加整个片段,同时仍然保留迭代childNodes 的可能性。无论如何,使用 documentFragment 解决了父节点问题。
【解决方案2】:

您必须在某处附加新元素。尝试将 DocumentFragment 对象与您创建的 div 结合使用:

function createElement(str) {
    var div = document.createElement('div');
    div.innerHTML = str;
    var container = document.createDocumentFragment();
    for (var i=0; i < div.childNodes.length; i++) {
        var node = div.childNodes[i].cloneNode(true);
        container.appendChild(node);
    }
    return container.childNodes;
}

它的开销更大,但它可以满足您的需求。请注意,DOM 元素的 .insertAdjacentHTML 成员函数将在 HTML5 中提供。

对于您传递的复杂字符串,它不是有效的 XHTML 语法 - 您不能将块元素作为 &lt;p&gt; 的子元素(&lt;h2&gt; 是块级元素)。

【讨论】:

  • 是的,我知道为什么它现在这样做了。愚蠢的错误,盯着它看了一会儿。所以我几乎拥有它,哦,好吧。谢谢!
猜你喜欢
  • 1970-01-01
  • 2019-01-28
  • 2020-01-14
  • 2021-12-13
  • 1970-01-01
  • 2019-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多