Javascript-将HTML附加到不带innerHTML的容器元素


167

我需要一种无需使用innerHTML即可将HTML附加到容器元素的方法。我不想使用innerHTML的原因是因为当使用这种方式时:

element.innerHTML += htmldata

它的工作原理是先替换所有html,然后再添加旧html和新html。这不好,因为它会重置动态媒体,例如嵌入式Flash视频...

我可以通过这种方式做到这一点:

var e = document.createElement('span');
e.innerHTML = htmldata;
element.appendChild(e);

但是这种方式的问题在于,我现在不想在文档中有多余的span标签。

那怎么办呢?谢谢!


1
为什么不使用Jquery?在下面查看我的详细答案。stackoverflow.com/a/50482776/5320562
Loukan ElKadi

Answers:


102

给出替代方案(因为使用DocumentFragment似乎无效):您可以通过迭代新生成的节点的子代并仅追加这些子代来模拟它。

var e = document.createElement('div');
e.innerHTML = htmldata;

while(e.firstChild) {
    element.appendChild(e.firstChild);
}

2
我以为我们正在寻找不使用“ innerHTML”的解决方案
kennydelacruz 18-10-18

1
@kennydelacruz:OP不想新的HTML 附加到现有的HTML,因为它会破坏并重新创建现有的元素。OP通过创建一个新元素并追加一个元素找到了解决方案,但他们不想添加其他元素。我只是扩展了该解决方案,以表明它们可以移动/附加新创建的元素,而不会影响现有元素。
菲利克斯·克林

我知道这已经很老了,但是谁能向我解释为什么可以遍历e.firstChild?
Toastgeraet19年

1
@Toastgeraet:这是例子并不迭代 e.firstChild。相反,它检查是否e有一个孩子,如果有,则将其移到元素上。
菲利克斯·克林

570

我很惊讶没有答案提到该insertAdjacentHTML()方法。检查出来这里。第一个参数是您想要附加字符串并采用的位置(“ beforebegin”,“ afterbegin”,“ beforeend”,“ afterend”)。在OP的情况下,您可以使用“ beforeend”。第二个参数就是html字符串。

基本用法:

var d1 = document.getElementById('one');
d1.insertAdjacentHTML('beforeend', '<div id="two">two</div>');

53
只是尝试了您的解决方案以及被接受。两者都有效,但是您只有2行且没有循环。听起来对我来说是赢家。
Corwin01年

3
供可能选择此路线的任何人参考:此方法在IE9中的表上效果不佳。
Corwin01 2012年

2
在Chrome中,它告诉我Uncaught TypeError: undefined is not a function
J86

19
这种隐藏的宝石需要更多的曝光。
赛斯

如果您尝试在非Node(仅是FYI)上使用此方法,则会收到错误消息。
亚历克斯W

15

阿尔纳菲对此问题有很好的答案。我想举一个他的代码示例供参考:

var childNumber = 3;

function addChild() {
  var parent = document.getElementById('i-want-more-children');
  var newChild = '<p>Child ' + childNumber + '</p>';
  parent.insertAdjacentHTML('beforeend', newChild);
  childNumber++;
}
body {
  text-align: center;
}
button {
  background: rgba(7, 99, 53, .1);
  border: 3px solid rgba(7, 99, 53, 1);
  border-radius: 5px;
  color: rgba(7, 99, 53, 1);
  cursor: pointer;
  line-height: 40px;
  font-size: 30px;
  outline: none;
  padding: 0 20px;
  transition: all .3s;
}
button:hover {
  background: rgba(7, 99, 53, 1);
  color: rgba(255,255,255,1);
}
p {
  font-size: 20px;
  font-weight: bold;
}
<button type="button" onclick="addChild()">Append Child</button>
<div id="i-want-more-children">
  <p>Child 1</p>
  <p>Child 2</p>
</div>

希望这对其他人有帮助。


2
我不想成为规则的坚持者,但我认为如果创建一个演示(jsfiddle,codepen等)然后通过使用编辑功能或提交评论将其添加到Alnafie的答案中会更好。不管您提供的信息有多有用,创建一个答案来证明另一个用户的答案都不是SO的工作原理。想象一下,如果每个用户都决定通过创建答案来演示另一个答案-这会变得很混乱。
马丁·詹姆斯

2
<div id="Result">
</div>

<script>
for(var i=0; i<=10; i++){
var data = "<b>vijay</b>";
 document.getElementById('Result').innerHTML += data;
}
</script>

使用“ + =”符号为div分配数据,您可以附加数据,包括以前的html数据


11
该问题专门要求使用element.innerHTML += data
musicnoth

1

这就是DocumentFragment本意。

var frag = document.createDocumentFragment();
var span = document.createElement("span");
span.innerHTML = htmldata;
for (var i = 0, ii = span.childNodes.length; i < ii; i++) {
    frag.appendChild(span.childNodes[i]);
}
element.appendChild(frag);

document.createDocumentFragment.childNodes


我只是测试了一下,所以不起作用。那应该如何使用?
鲍勃

你从哪里来(a)?是错字吗
Ash Burlaczenko 2011年

1
是的,这是一个错字,应该是e。我认为您不能将innerHTML用作片段。这是行不通的
鲍勃

@Bob我去使用jQuery。
Raynos 2011年

jQuery不不!我不会仅出于一个小功能就包括jQuery:\只是太过分了
鲍勃·

-1

如何钓鱼以及如何使用严格的代码。这篇文章的底部需要两个必备功能。

xml_add('before', id_('element_after'), '<span xmlns="http://www.w3.org/1999/xhtml">Some text.</span>');

xml_add('after', id_('element_before'), '<input type="text" xmlns="http://www.w3.org/1999/xhtml" />');

xml_add('inside', id_('element_parent'), '<input type="text" xmlns="http://www.w3.org/1999/xhtml" />');

添加多个元素(名称空间只需要在父元素上):

xml_add('inside', id_('element_parent'), '<div xmlns="http://www.w3.org/1999/xhtml"><input type="text" /><input type="button" /></div>');

动态可重用代码:

function id_(id) {return (document.getElementById(id)) ? document.getElementById(id) : false;}

function xml_add(pos, e, xml)
{
 e = (typeof e == 'string' && id_(e)) ? id_(e) : e;

 if (e.nodeName)
 {
  if (pos=='after') {e.parentNode.insertBefore(document.importNode(new DOMParser().parseFromString(xml,'application/xml').childNodes[0],true),e.nextSibling);}
  else if (pos=='before') {e.parentNode.insertBefore(document.importNode(new DOMParser().parseFromString(xml,'application/xml').childNodes[0],true),e);}
  else if (pos=='inside') {e.appendChild(document.importNode(new DOMParser().parseFromString(xml,'application/xml').childNodes[0],true));}
  else if (pos=='replace') {e.parentNode.replaceChild(document.importNode(new DOMParser().parseFromString(xml,'application/xml').childNodes[0],true),e);}
  //Add fragment and have it returned.
 }
}
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.