การต่อท้ายสตริง HTML เข้ากับ DOM


121

วิธีต่อท้ายสตริง HTML นี้

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

ไปยัง DIV ด้วย ID 'test'ซึ่งอยู่ใน DOM?

(Btw div.innerHTML += str;ไม่เป็นที่ยอมรับ)

คำตอบ:


243

ใช้insertAdjacentHTMLหากมีหรือใช้ทางเลือกบางประเภท insertAdjacentHTML รับการสนับสนุนในเบราว์เซอร์ในปัจจุบันทั้งหมด

div.insertAdjacentHTML( 'beforeend', str );

การสาธิตสด: http://jsfiddle.net/euQ5n/


1
@alex เป็นแนวคิดเดียวกันคือการแยกวิเคราะห์สตริง HTML และใส่ลงใน DOM แต่ฟังก์ชันการทำงานแตกต่างกัน - innerHTMLใส่สตริงลงในองค์ประกอบ (แทนที่ชายด์ทั้งหมด) ในขณะที่insertAdjacentHTMLใส่ (1) ก่อนองค์ประกอบ (2) หลังองค์ประกอบ (3) ภายในองค์ประกอบก่อนลูกคนแรกหรือ (4) ภายในองค์ประกอบหลังลูกคนสุดท้าย
Šime Vidas

3
@alex insertAdjacentHTMLเร็วกว่าการต่อท้ายinnerHTMLเนื่องจากinsertAdjacentHTMLไม่ทำให้เป็นอนุกรมและแยกย่อยที่มีอยู่ขององค์ประกอบ
hsivonen

2
นอกจากนี้ยังinsertAdjacentHTMLรักษาค่าขององค์ประกอบฟอร์มที่เปลี่ยนแปลงในขณะที่การต่อท้ายเพื่อinnerHTMLสร้างองค์ประกอบใหม่และสูญเสียบริบทของฟอร์มทั้งหมด
Brandon Gano

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 ของเบราว์เซอร์ฉันอยากรู้ ...
Šime Vidas

1
@ Šime - ฉันคิดว่ามีเพียงสองวิธีในการใช้โปรแกรมแยกวิเคราะห์ HTML ของเบราว์เซอร์คือ innerHTML และ document.write และถ้าคุณคิดว่า innerHTML เป็นการแฮ็ก ...
Alohci

@Alohci มีอีกวิธีหนึ่งคือinsertAdjacentHTML .
Šime Vidas

1
@ Šime - ขอบคุณ ฉันพบเวอร์ชัน WHATWG อยู่ในข้อมูลจำเพาะDOM Parsing และ Serialization มันบ่งชี้ว่าเช่นเดียวกับ innerHTML และ insertAdjacentHTML มี outerHTML และฉันคิดว่า createContextualFragment
Alohci

16

ประสิทธิภาพ

AppendChild(E) เร็วกว่าโซลูชันอื่น ๆ บน Chrome และ Safari มากกว่า 2 เท่าinsertAdjacentHTML(F) เร็วกว่าใน Firefox innerHTML=(B) (อย่าสับสนกับ+=(A)) เป็นวิธีที่รวดเร็วที่สองในเบราว์เซอร์และมันก็เป็นประโยชน์มากขึ้นกว่าอีและเอฟ

รายละเอียด

ตั้งค่าสภาพแวดล้อม (2019.07.10) MacOs High Sierra 10.13.4 บน Chrome 75.0.3770 (64 บิต), Safari 11.1.0 (13604.5.6), Firefox 67.0.0 (64 บิต)

ใส่คำอธิบายภาพที่นี่

  • บน 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

ความคิดที่จะใช้ในองค์ประกอบตัวกลางและจากนั้นย้ายทั้งหมดของโหนดลูกของตนเพื่อที่คุณต้องการจริงๆพวกเขาผ่านทางinnerHTMLappendChild

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 ขอขอบคุณสำหรับการกล่าวขวัญ ฉันกำลังค้นหาวิธีสร้าง html ที่มีสคริปต์ให้ทำงานก็ต่อเมื่อผู้ใช้ยินยอมที่จะตั้งค่าคุกกี้
schliflo

3

แฮ็คด่วน:


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

ใช้กรณี :

1: บันทึกเป็นไฟล์. html และเรียกใช้ใน chrome หรือ firefox หรือ edge (IE เคยชิน)

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 มาที่นี่เพื่อหาวิธีแก้ปัญหาอย่างรวดเร็ว ฉันแค่อยากเห็นผลลัพธ์ของโค้ด scratchpad สองสามบรรทัดวิธีแก้ปัญหาอื่น ๆ ใช้งานได้มากเกินไป


1

เหตุใดจึงไม่เป็นที่ยอมรับ

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

คงเป็นวิธีการทำตามตำรา


4
มันจะฆ่าตัวจัดการเหตุการณ์ที่แนบมากับ#testว่า ที่ไม่พึงปรารถนาโดยทั่วไป
alex

น่าสนใจว่ามันทำอย่างนั้น ดูเหมือนจะไม่สมเหตุสมผลจริงๆ
Nick Brunt

2
เป็นเหตุผลที่ฉันเดาว่าถ้าคุณคิดเกี่ยวกับการต่ออนุกรมของ HTML เป็นสตริงแล้วตั้งค่า HTML กลับ
alex

ฉันเดาว่า JavaScript จะต้องถูกเรียกใช้อีกครั้งเพื่อรีเซ็ตตัวจัดการเหตุการณ์ พอใช้.
Nick Brunt

1
@Nick คุณไม่ต้องการสตริง (ทำให้เป็นอนุกรม) เป็นส่วนหนึ่งของ DOM เพียงเพื่อให้คุณสามารถเชื่อมต่อกับสตริงอื่นแล้วแยกวิเคราะห์สิ่งทั้งหมดกลับไปที่ DOM ดังที่อเล็กซ์กล่าวการทำให้เป็นอนุกรมจะไม่บันทึกตัวจัดการเหตุการณ์ที่ถูกผูกไว้ (เหนือสิ่งอื่นใด) แม้ว่าการทำให้เป็นอนุกรมสามารถจับภาพทุกอย่างได้ แต่คุณก็ยังไม่อยากทำ
Šime Vidas

0

สิ่งนี้สามารถแก้ได้

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

3
ยินดีต้อนรับสู่ Stack overflow โปรดอธิบายรหัสของคุณเป็นส่วนหนึ่งของคำตอบเพื่อให้บริบทบางอย่างแทนที่จะวางโค้ดยาว ๆ เพียงบรรทัดเดียว แม้ว่าคุณจะเข้าใจ แต่คนอื่นอาจไม่เข้าใจว่ามันทำอะไร
เงินกู้เบอร์เกอร์

0

InnerHTML ล้างข้อมูลทั้งหมดเช่นเหตุการณ์สำหรับโหนดที่มีอยู่

ต่อท้ายเด็กด้วย firstChild เพิ่มลูกคนแรกเท่านั้นใน innerHTML ตัวอย่างเช่นหากเราต้องต่อท้าย:

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

เฉพาะ text1 เท่านั้นที่จะปรากฏขึ้น

แล้วสิ่งนี้:

เพิ่มแท็กพิเศษใน innerHTML โดยต่อท้ายเด็กจากนั้นแก้ไข outerHTML โดยการลบแท็กที่เราสร้างขึ้น ไม่รู้ว่ามันฉลาดแค่ไหน แต่มันใช้ได้สำหรับฉันหรือคุณอาจเปลี่ยน outerHTML เป็น innerHTML เพื่อที่จะได้ไม่ต้องใช้ function replace

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>


0

สั้นที่สุด - 18 ตัวอักษร (อย่าสับสน+=(พูดถึงโดย OP) มี=รายละเอียดเพิ่มเติมที่นี่ )

test.innerHTML=str

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