如何在两个DOM节点之间插入HTML字符串?

13

请考虑以下 DOM 片段:

<div id="div-1">foo</div>
<div id="div-2">bar</div>

是否可以在不使用document.createElement创建一个新元素并设置其innerHTML属性的情况下,将包含HTML标记的字符串(编辑:用于呈现标记)插入到div之间?

4个回答

20

大多数浏览器支持使用element#insertAdjacentHTML()方法,该方法终于在HTML5规范中成为标准。不幸的是,Firefox 7及以下版本不支持此方法,但我找到了一种使用范围(ranges)的解决方法来插入HTML。我已经改编了它以适应您的情况:

var el = document.getElementById("div-2"),
    html = "<span>Some HTML <b>here</b></span>";

// Internet Explorer, Opera, Chrome, Firefox 8+ and Safari
if (el.insertAdjacentHTML)
    el.insertAdjacentHTML ("beforebegin", html);
else {
    var range = document.createRange();
    var frag = range.createContextualFragment(html);
    el.parentNode.insertBefore(frag, el);
}

现场示例:http://jsfiddle.net/AndyE/jARTf/


10
这只适用于纯文本,这是我阅读您的原始问题的方式(有关包含标签的字符串的更新,请参见下文):
var div = document.getElementById('div-2');
var textNode = document.createTextNode('your text');
div.parentNode.insertBefore(textNode, div);

实时示例

如果您从以下内容开始:

<div id="div-1">foo</div>div id="div-2">bar</div>

请注意,它们之间没有空格。那么,以上内容的结果与以下HTML完全相同:

<div id="div-1">foo</div>your text<div id="div-2">bar</div>

如果您的div之间确实有空格,那么在这里已经有一个文本节点,上面的代码会在它旁边插入另一个文本节点。对于几乎所有情况来说,这并不重要,但如果您介意,可以选择将内容添加到现有的文本节点中:

var text = 'your text';
var div = document.getElementById('div-2');
var prev = div.previousSibling;
if (prev && prev.nodeType == 3) { // 3 == TEXT_NODE
  // Prev is a text node, append to it
  prev.nodeValue = prev.nodeValue + text;
}
else {
  // Prev isn't a text node, insert one
  var textNode = document.createTextNode(text);
  div.parentNode.insertBefore(textNode, div);
}

实时演示

W3C文档链接: insertBefore, createTextNode

包含HTML标签

在您修改后的问题中,您说想要包含标签以进行解释。虽然这是可能的,但有些麻烦。首先,您需要将HTML字符串放入元素中,然后移动内容,如下所示:

var text, div, tempdiv, node, next, parent;

// The text
text = 'your text <em>with</em> <strong>tags</strong> in it';

// Get the element to insert in front of, and its parent
div = document.getElementById('div-2');
parent = div.parentNode;

// Create a temporary container and render the HTML to it
tempdiv = document.createElement('div');
tempdiv.innerHTML = text;

// Walk through the children of the container, moving them
// to the desired target. Note that we have to be sure to
// grab the node's next sibling *before* we move it, because
// these things are live and when we moev it, well, the next
// sibling will become div-2!
node = tempdiv.firstChild;
next = node.nextSibling;
while (node) {
  parent.insertBefore(node, div);
  node = next;
  next = node ? node.nextSibling : undefined;
}

实时例子

但是这里有一些需要注意的地方,你需要根据插入内容的适当容器元素进行选择。例如,我们不能在上述代码中使用<tr>,因为我们要将其插入到div而不是tbody中,这是无效的,结果取决于具体实现。这些复杂性就是我们需要库来帮助我们的原因。你已经要求了一个原始的DOM答案,那就是上面的内容,但我真的建议你查看jQueryClosurePrototypeYUI其他几个库,它们会为你解决很多问题。


也许我没有理解你的意思,但这正是我试图避免的,将HTML字符串包装成标签。 - actual
不使用通过document.createElement创建的另一个div进行包装。 - mplungjan
不,它们不会这样做 -- 这就是文本节点的一部分所在。我看到你编辑了你的问题。好的,第三次编辑,它可能的,只是很麻烦。 - T.J. Crowder
“我希望我可以接受多个答案……” 不用担心! :-) - T.J. Crowder
了不起的工作。在你的第一次编辑之前,我已经点赞了,但自那以后,我希望我能再次点赞以表彰所付出的努力。 - Andy E
显示剩余4条评论

0
var neuB = document.createElement("b");
var neuBText = document.createTextNode("mit fettem Text ");
neuB.appendChild(neuBText);
document.getElementById("derText").insertBefore(neuB, document.getElementById("derKursiveText"));

您正在搜索:insertBefore


0

使用jQuery非常简单:

$("#div-1").after("Other tag here!!!");

请参阅:jquery.after

很明显,JavaScript不是一个纯JavaScript解决方案。


如何将其转换为纯JS + DOM? - actual
1
jQuery在我上次看到时是用javascript编写的 :) - mplungjan
1
由于在SO上大多数JS答案都涉及jQuery,所以几乎可以认为jQuery==JavaScript ;)(但仍然不是===)。 - mplungjan
@mplungjan:然而,用纯jQuery回答JavaScript / HTML / DOM问题是不恰当且不正确的。(如果您提供一个纯JS答案然后说“但是如果您使用库X会更容易”,那是可以的。) - T.J. Crowder
我在网上和其他地方看到很多答案,甚至不提jQuery,只是给出了jQuery的例子。这就是生活。 - mplungjan
好的,好的,不要生气。解决方案并不是纯JavaScript,这很明显,我相信@actual也意识到了。但是不要生气。这不是一场竞赛! - angelcervera

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接