Javascript - ต่อท้าย HTML เข้ากับองค์ประกอบคอนเทนเนอร์โดยไม่ต้อง InnerHTML


167

ฉันต้องการวิธีผนวก HTML เข้ากับองค์ประกอบคอนเทนเนอร์โดยไม่ต้องใช้ innerHTML เหตุผลที่ฉันไม่ต้องการใช้ innerHTML ก็เพราะเมื่อมันใช้งานแบบนี้:

element.innerHTML += htmldata

ใช้งานได้โดยแทนที่ html ทั้งหมดก่อนที่จะเพิ่ม html เก่าบวก html ใหม่ สิ่งนี้ไม่ดีเนื่องจากรีเซ็ตสื่อแบบไดนามิกเช่นวิดีโอแฟลชในตัว ...

ฉันสามารถทำได้ด้วยวิธีนี้ซึ่งได้ผล:

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

อย่างไรก็ตามปัญหาของวิธีนี้คือมีแท็ก span พิเศษในเอกสารที่ฉันไม่ต้องการ

วิธีนี้สามารถทำได้? ขอบคุณ!


1
ทำไมไม่ใช้ Jquery ตรวจสอบคำตอบโดยละเอียดของฉันด้านล่าง stackoverflow.com/a/50482776/5320562
Loukan ElKadi

คำตอบ:


102

หากต้องการให้ทางเลือกอื่น ( DocumentFragmentดูเหมือนว่าการใช้ไม่ได้ผล): คุณสามารถจำลองมันได้โดยทำซ้ำกับโหนดย่อยของโหนดที่สร้างขึ้นใหม่และต่อท้ายโหนดเหล่านั้นเท่านั้น

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

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

2
ฉันคิดว่าเรากำลังมองหาวิธีแก้ปัญหาที่ไม่ได้ใช้ "innerHTML"
kennydelacruz

1
@kennydelacruz: OP ไม่ต้องการผนวก HTML ใหม่ไปยัง HTML ที่มีอยู่เพราะมันจะทำลายและสร้างองค์ประกอบที่มีอยู่ใหม่ OP พบวิธีแก้ไขด้วยการสร้างองค์ประกอบใหม่และผนวก แต่พวกเขาไม่ต้องการเพิ่มองค์ประกอบเพิ่มเติม ฉันเพิ่งขยายโซลูชันนั้นเพื่อแสดงว่าพวกเขาสามารถย้าย / ผนวกองค์ประกอบที่สร้างขึ้นใหม่ซึ่งไม่ส่งผลกระทบต่อองค์ประกอบที่มีอยู่
เฟลิกซ์คลิง

ฉันรู้ว่ามันเก่า แต่ใคร ๆ ก็สามารถอธิบายให้ฉันฟังได้ว่าทำไมใครคนหนึ่งถึงทำซ้ำได้มากกว่า e.firstChild
Toastgeraet

1
@Toastgeraet: นี่คือตัวอย่างที่จะไม่ทำซ้ำมากกว่า e.firstChildค่อนข้างจะตรวจสอบว่าeมีเด็กและถ้าใช่ย้ายเด็กคนนั้นไปที่องค์ประกอบ
เฟลิกซ์คลิง

570

ฉันประหลาดใจที่ไม่มีคำตอบที่กล่าวถึงinsertAdjacentHTML()วิธีการ ตรวจสอบออกที่นี่ พารามิเตอร์แรกคือตำแหน่งที่คุณต้องการให้สตริงต่อท้ายและรับ ("beforebegin", "afterbegin", "beforeend", "afterend") ในสถานการณ์ของ OP คุณจะต้องใช้ "ก่อนหน้า" พารามิเตอร์ที่สองเป็นเพียงสตริง html

การใช้งานขั้นพื้นฐาน:

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

53
เพียงลองวิธีการแก้ปัญหาของคุณเช่นเดียวกับการยอมรับ ทั้งสองทำงาน แต่ของคุณมีเพียง 2 บรรทัดและไม่มีลูป เสียงเหมือนผู้ชนะสำหรับฉัน
Corwin01

3
สำหรับการอ้างอิงถึงใครก็ตามที่อาจเลือกเส้นทางนี้: วิธีนี้เล่นได้ไม่ดีกับตารางใน IE9
Corwin01

2
ใน Chrome มันบอกฉันUncaught TypeError: undefined is not a function!
J86

19
อัญมณีที่ซ่อนเร้นนี้ต้องการการเปิดเผยที่มากกว่า
เซท

คุณจะได้รับข้อผิดพลาดหากคุณพยายามใช้วิธีนี้กับสิ่งที่ไม่ใช่โหนดเพียงแค่ FYI
Alex W

15

alnafie มีคำตอบที่ดีสำหรับคำถามนี้ ฉันต้องการให้ตัวอย่างของรหัสของเขาสำหรับการอ้างอิง:

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 โดยไม่คำนึงว่าข้อมูลที่คุณให้นั้นมีประโยชน์เพียงใด ลองนึกภาพถ้าผู้ใช้ทุกคนตัดสินใจที่จะสาธิตคำตอบอื่นโดยสร้างคำตอบ - มันจะยุ่งเหยิง
Martin James

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เฉพาะ
ดนตรี

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


ฉันเพิ่งทดสอบสิ่งนี้และมันไม่ทำงาน เป็นวิธีที่ควรใช้หรือไม่
Bob

คุณ(a)มาจากไหน นั่นคือการพิมพ์ผิด
Ash Burlaczenko

1
ใช่นั่นคือการพิมพ์ผิดมันควรจะเป็น e ฉันไม่คิดว่าคุณสามารถใช้ innerHTML เพื่อแยกส่วนได้ สิ่งนี้ไม่ทำงาน
Bob

@Bob ฉันได้ไปใช้ cop-out ใช้ jQuery
Raynos

jQuery ไม่ไม่! ฉันจะไม่รวม jQuery สำหรับฟังก์ชั่นเล็ก ๆ เพียงตัวเดียว: \ มันแค่ overkill
Bob

-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.
 }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.