将HTML字符串追加到DOM


121

如何附加这个HTML字符串

var str = '<p>Just some <span>text</span> here</p>';

到具有'test'DOM中ID的DIV ?

(顺便说一句div.innerHTML += str;是不可接受的。)

Answers:


242

使用(insertAdjacentHTML如果可用),否则使用某种后备。当前所有浏览器均支持 insertAdjacentHTML 。

div.insertAdjacentHTML( 'beforeend', str );

现场演示: http //jsfiddle.net/euQ5n/


1
@alex是同一概念:解析HTML字符串并将其放入DOM。但是功能有所不同- innerHTML将字符串放入元素(替换所有子元素),而insertAdjacentHTML将字符串(1)放在元素之前,(2)元素之后,(3)在元素内的第一个子元素之前,或(4)在最后一个孩子之后的元素中。
西米·维达斯

3
@alex insertAdjacentHTML比追加到快innerHTML,因为insertAdjacentHTML它不会序列化和解析元素的现有子元素。
hsivonen

2
同样,insertAdjacentHTML保持更改后的表单元素的值,而将追加到innerHTMLre会重建元素并丢失所有表单上下文。
布兰登·加诺

20

这可以接受吗?

var child = document.createElement('div');
child.innerHTML = str;
child = child.firstChild;
document.getElementById('test').appendChild(child);

jsFiddle

但是尼尔的答案是一个更好的解决方案。


1
@Šime使用DOM API 总是感觉很像黑客:P您是否愿意在 使用字符串的情况下反序列化innerHTML
alex

嗯,是的,如果有另一种方式来利用浏览器的HTML解析器,我很想知道...
森那维达斯

1
@Šime-我认为只有两种方法可以利用浏览器的HTML解析器,innerHTML和document.write。而且,如果您认为innerHTML是一种入侵……
Alohci 2011年

@Alohci有另一种方法:insertAdjacentHTML
森达维达斯

1
@Šime-谢谢。我找到了WHATWG版本。它在DOM解析和序列化规范中。它表示除了innerHTML和insertAdjacentHTML之外,还有outerHTML和我认为的createContextualFragment。
Alohci 2011年

16

性能

AppendChild(E)在chrome和safari上比其他解决方案快两倍以上,insertAdjacentHTML(F)在Firefox上最快。在innerHTML=(B)(不要混淆+=(A))是在所有的浏览器第二快速的解决方案,这是更方便的比E和F.

细节

在Chrome 75.0.3770(64位),Safari 11.1.0(13604.5.6),Firefox 67.0.0(64位)上设置环境(2019.07.10)MacOs High Sierra 10.13.4

在此处输入图片说明

  • Chrome E(每秒140k次操作)最快,B(47k)和F(46k)次之,A(332)最快
  • 在Firefox上F(94k)最快,然后B(80k),D(73k),E(64k),C(21k)最慢是A(466)
  • 在Safari E(207k)上最快,然后是B(89k),F(88k),D(83k),C(25k),最慢的是A(509)

您可以在此处重播测试


12

这个想法是innerHTML在中间元素上使用,然后将其所有子节点移动到您真正想要的子节点appendChild

var target = document.getElementById('test');
var str = '<p>Just some <span>text</span> here</p>';

var temp = document.createElement('div');
temp.innerHTML = str;
while (temp.firstChild) {
  target.appendChild(temp.firstChild);
}

这样可以避免清除所有事件处理程序,div#test但仍允许您附加HTML字符串。


3

正确的方法是使用insertAdjacentHTML。在Firefox 8之前的版本中,Range.createContextualFragment如果您不str包含任何script标记,则可以退回使用。

如果str包含script标签,则需要在插入片段之前script从返回的片段中删除元素createContextualFragment。否则,脚本将运行。(将insertAdjacentHTML脚本标记为不可执行。)


谢谢您的提及createContextualFragment 。我正在寻找一种方法,以使仅当用户同意设置Cookie时,脚本才会包含某些html。
schliflo

3

快速黑客


<script>
document.children[0].innerHTML="<h1>QUICK_HACK</h1>";
</script>

用例

1:另存为.html文件,然后在chrome或firefox或edge中运行。(即不会工作)

2:在http://js.do中使用

实际应用中: http //js.do/HeavyMetalCookies/quick_hack

细分为评论:

<script>

//: The message "QUICK_HACK" 
//: wrapped in a header #1 tag.
var text = "<h1>QUICK_HACK</h1>";

//: It's a quick hack, so I don't
//: care where it goes on the document,
//: just as long as I can see it.
//: Since I am doing this quick hack in
//: an empty file or scratchpad, 
//: it should be visible.
var child = document.children[0];

//: Set the html content of your child
//: to the message you want to see on screen.
child.innerHTML = text;

</script>

我发布的原因:

JS.do有两个必须具备的条件:

  1. 没有自动完成
  2. 垂直显示器友好

但是不显示console.log消息。来到这里寻找快速解决方案。我只想看几行暂存器代码的结果,其他解决方案却工作太多。


1

为什么不能接受?

document.getElementById('test').innerHTML += str

将是教科书上的做法。


4
它将杀死附加的事件处理程序#test。这通常是不希望的。
alex

有趣的是它做到了。看起来似乎不合逻辑。
Nick Brunt

2
如果您考虑将HTML序列化为字符串然后再将HTML重新设置,这是合乎逻辑的。
alex

我猜想必须重新运行JavaScript才能重置事件处理程序。很公平。
Nick Brunt

1
@Nick您不想只对DOM的一部分进行字符串化(序列化),以便可以将其与另一个字符串连接在一起,然后将整个内容解析回DOM中。正如alex所说,序列化不会记录绑定的事件处理程序(以及其他内容)。即使他的序列化可以捕获所有内容,您仍然不想这样做。
森达维达斯

0

这样可以解决

 document.getElementById("list-input-email").insertAdjacentHTML('beforeend', '<div class=""><input type="text" name="" value="" class="" /></div>');

3
欢迎使用Stack溢出。请解释您的代码,作为提供某些上下文的答案的一部分,而不仅仅是粘贴一行很长的代码。尽管您了解它,但其他人可能不了解它在做什么。
loan.burger

0

InnerHTML清除现有节点的所有数据(如事件)

将带有firstChild的child追加到innerHTML中仅添加第一个孩子。例如,如果我们必须追加:

 <p>text1</p><p>text2</p>

仅显示text1

那这个呢:

通过追加子项将特殊标签添加到innerHTML,然后通过删除我们创建的标签来编辑externalHTML。不知道它有多聪明,但是对我有用,否则您可以将externalHTML更改为innerHTML,因此不必使用功能替换

function append(element, str)
{

  var child = document.createElement('someshittyuniquetag');
		
  child.innerHTML = str;

  element.appendChild(child);

  child.outerHTML = child.outerHTML.replace(/<\/?someshittyuniquetag>/, '');

// or Even child.outerHTML = child.innerHTML


  
}
<div id="testit">
This text is inside the div
<button onclick="append(document.getElementById('testit'), '<button>dadasasdas</button>')">To div</button>
<button onclick="append(this, 'some text')">to this</button>
</div>


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.