การสร้างองค์ประกอบ DOM ใหม่จากสตริง HTML โดยใช้วิธี DOM แบบในตัวหรือต้นแบบ


621

ฉันมีสตริง HTML '<li>text</li>'ที่เป็นตัวแทนของธาตุ: ฉันต้องการที่จะผนวกเข้ากับองค์ประกอบใน DOM ( ulในกรณีของฉัน) ฉันจะทำสิ่งนี้กับ Prototype หรือเมธอด DOM ได้อย่างไร

(ฉันรู้ว่าฉันสามารถทำได้อย่างง่ายดายใน jQuery แต่น่าเสียดายที่เราไม่ได้ใช้ jQuery)


ขออภัยคุณพยายามทำอะไรให้สำเร็จ สตริง HTML -> องค์ประกอบ dom?
Crescent Fresh

36
โชคไม่ดีที่โซลูชันเหล่านี้อ้อมไป ฉันหวังว่าคณะกรรมการมาตรฐานจะระบุสิ่งที่คล้ายกัน:var nodes = document.fromString("<b>Hello</b> <br>");
Sridhar Sarnobat


1
ฉันมีปัญหากับข้างต้นเพราะฉันมีคุณลักษณะที่จำเป็นต้องผ่านไปมาและฉันไม่รู้สึกเหมือนกับการแยกวิเคราะห์: "<table id = '5ccf9305-4b10-aec6-3c55-a6d218bfb107' class = 'data-table การแสดงผลแบบแถวชายแดน 'cellspacing =' 0 'width =' 100% '> </table> "ดังนั้นฉันใช้: $ (" <table id =' 5ccf9305-4b10-aec6-3c55-a6d218bfb107 'class =' ​​data แสดงตารางแถวชายแดน 'cellspacing =' 0 'width =' 100% '> </table> ")
stevenlacerda

คำตอบ:


818

หมายเหตุ:เบราว์เซอร์ปัจจุบันส่วนใหญ่รองรับ<template>องค์ประกอบHTML ซึ่งเป็นวิธีที่เชื่อถือได้มากขึ้นในการเปลี่ยนการสร้างองค์ประกอบจากสตริง ดูคำตอบมาร์ค Amery ของรายละเอียดด้านล่าง

สำหรับเบราว์เซอร์รุ่นเก่าและโหนด / jsdom : (ซึ่งยังไม่รองรับ<template>องค์ประกอบในขณะที่เขียน) ให้ใช้วิธีการต่อไปนี้ มันเป็นสิ่งเดียวกันกับที่ห้องสมุดใช้ในการรับองค์ประกอบ DOM จากสตริง HTML ( โดยมีงานพิเศษสำหรับ IEในการแก้ไขข้อบกพร่องด้วยการนำไปใช้innerHTML)

function createElementFromHTML(htmlString) {
  var div = document.createElement('div');
  div.innerHTML = htmlString.trim();

  // Change this to div.childNodes to support multiple top-level nodes
  return div.firstChild; 
}

หมายเหตุว่าแตกต่างจาก HTML แม่แบบนี้จะไม่ทำงานสำหรับองค์ประกอบบางอย่างที่ไม่สามารถถูกต้องตามกฎหมายจะเป็นบุตรของ<div>เช่น<td>s

หากคุณใช้ห้องสมุดอยู่แล้วฉันขอแนะนำให้คุณใช้วิธีการที่ได้รับอนุมัติจากห้องสมุดในการสร้างองค์ประกอบจากสตริง HTML:

  • ต้นแบบมีคุณลักษณะนี้ตัวเป็นของวิธีการupdate()
  • jQuery มีการนำไปใช้ในjQuery(html)และjQuery.parseHTMLวิธีการต่างๆ

1
วิธีการตั้งค่า innerHTML เป็น div ที่สร้างโดยใช้ jQuery โดยไม่ใช้การมอบหมาย InnerHTML ที่ไม่ปลอดภัยนี้ (div.innerHTML = "ค่าบางอย่าง")
Shivanshu Goyal

12
ชื่อฟังก์ชั่นcreateElementFromHTML เป็นความเข้าใจผิดเนื่องจากdiv.firstChildผลตอบแทนNodeที่ไม่ได้เป็นเช่นไม่สามารถHTMLElement node.setAttributeเพื่อสร้างElementผลตอบแทนdiv.firstElementChildจากฟังก์ชั่นแทน
Semmel

ขอบคุณการ<div>ห่อ HTML ที่ฉันเพิ่มด้วย.innerHTMLนั้นน่ารำคาญ .firstChildฉันไม่เคยคิดว่าการใช้
อีวาน

ฉันพยายามแยก SVG ภายในส่วนที่สร้างขึ้นdivและผลลัพธ์ก็คือ[object SVGSVGElement]ในขณะที่บันทึกของคอนโซลให้องค์ประกอบ DOM ที่ถูกต้องกับฉัน ผมทำอะไรผิดหรือเปล่า?
ed1nh0

1
ฉันจะใช้ firstElementChild แทน firstChild (ดูw3schools.com/jsref/prop_element_firstelementchild.asp ) เพราะถ้ามีช่องว่างด้านหน้าหรือท้ายเทมเพลต firstChild จะส่งคืนข้อความว่างเปล่าโหนด
Chris Panayotoff

342

HTML 5 แนะนำ<template>องค์ประกอบที่สามารถใช้เพื่อวัตถุประสงค์นี้ (ตามที่อธิบายไว้ในตอนนี้ในข้อมูลจำเพาะ WhatWGและMDN )

<template>องค์ประกอบที่ใช้ในการประกาศชิ้นส่วนของ HTML ที่สามารถนำไปใช้ในสคริปต์ องค์ประกอบถูกแสดงใน DOM HTMLTemplateElementซึ่งมี.contentคุณสมบัติDocumentFragmentประเภทเพื่อให้การเข้าถึงเนื้อหาของเทมเพลต ซึ่งหมายความว่าคุณสามารถแปลงสตริง HTML เพื่อองค์ประกอบ DOM โดยการตั้งค่าinnerHTMLของ<template>องค์ประกอบแล้วเอื้อมมือเข้าไปในtemplateของ.contentสถานที่ให้บริการ

ตัวอย่าง:

/**
 * @param {String} HTML representing a single element
 * @return {Element}
 */
function htmlToElement(html) {
    var template = document.createElement('template');
    html = html.trim(); // Never return a text node of whitespace as the result
    template.innerHTML = html;
    return template.content.firstChild;
}

var td = htmlToElement('<td>foo</td>'),
    div = htmlToElement('<div><span>nested</span> <span>stuff</span></div>');

/**
 * @param {String} HTML representing any number of sibling elements
 * @return {NodeList} 
 */
function htmlToElements(html) {
    var template = document.createElement('template');
    template.innerHTML = html;
    return template.content.childNodes;
}

var rows = htmlToElements('<tr><td>foo</td></tr><tr><td>bar</td></tr>');

โปรดทราบว่าวิธีการที่คล้ายกันซึ่งใช้องค์ประกอบคอนเทนเนอร์ที่แตกต่างกันเช่น adivค่อนข้างใช้งานไม่ได้ HTML มีข้อ จำกัด เกี่ยวกับประเภทองค์ประกอบที่ได้รับอนุญาตให้มีอยู่ภายในประเภทองค์ประกอบอื่น ๆ ตัวอย่างเช่นคุณไม่สามารถใส่เป็นเด็กโดยตรงของtd divสิ่งนี้จะทำให้องค์ประกอบเหล่านี้หายไปถ้าคุณพยายามตั้งค่าinnerHTMLของ a divให้มีองค์ประกอบเหล่านั้น เนื่องจาก<template>ไม่มีข้อ จำกัด ดังกล่าวในเนื้อหาข้อบกพร่องนี้จึงไม่มีผลเมื่อใช้เทมเพลต

อย่างไรก็ตามtemplateไม่รองรับเบราว์เซอร์เก่าบางตัว เมื่อวันที่มกราคม 2018 ฉันสามารถใช้ ...ประมาณการ90% ของผู้ใช้ทั่วโลกกำลังใช้เบราว์เซอร์ที่สนับสนุนtemplate s โดยเฉพาะอย่างยิ่งไม่มีเวอร์ชันใดของ Internet Explorer ที่รองรับ Microsoft ไม่ได้ใช้การtemplateสนับสนุนจนกว่าจะมีการเปิดตัว Edge

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


9
วิธีการที่ทันสมัย ทดสอบบน Opera แล้วอย่าลืม IE
Adi Prasetyo

2
นี่เป็นวิธีที่มีประสิทธิภาพและสะอาดมาก อย่างไรก็ตาม (อย่างน้อยใน Chrome 50) นี่จะเป็นการจัดการแท็กสคริปต์ กล่าวอีกนัยหนึ่งการใช้วิธีนี้ในการสร้างแท็กสคริปต์แล้วต่อท้ายเอกสาร (เนื้อหาหรือส่วนหัว) จะไม่ส่งผลให้แท็กถูกประเมินและทำให้สคริปต์ไม่ทำงาน (ซึ่งอาจจะเกิดจากการออกแบบถ้าการประเมินผลที่เกิดขึ้นในแนบ; ฉันไม่สามารถพูดได้อย่างแน่นอน.)
shanef22

1
น่ารัก! คุณสามารถค้นหาองค์ประกอบโดยทำสิ่งที่ชอบ: template.content.querySelector ("img");
Roger Gajraj

1
@Crescent Fresh: ยุติธรรมมากฉันรู้สึกประทับใจที่คุณต้องการคำตอบของคุณไปเพราะคุณบอกว่าตอนนี้มันไม่เกี่ยวข้องเลยขอโทษด้วย การประนีประนอมที่ดีจะเป็นการเพิ่มคำแถลงให้กับผู้อ่านที่ชี้ไปยังคำตอบของคุณดังที่ได้มีการพูดคุยกันในเมตาดาต้าแล้วเราหวังว่าสงครามการแก้ไขจะไม่ได้มาจากที่นั่น
BoltClock

2
มีปัญหาอย่างหนึ่งกับมัน หากคุณมีแท็กในนั้นที่มีช่องว่างภายใน (!) ตอนเริ่มต้นหรือสิ้นสุดแท็กนั้นจะถูกลบออก! อย่าเข้าใจฉันผิดนี่ไม่เกี่ยวกับช่องว่างที่ถูกลบโดยhtml.trimแต่โดยการแยกวิเคราะห์ภายในของการตั้งค่า innerHTML ในกรณีของฉันมันลบช่องว่างที่สำคัญเป็นส่วนหนึ่งของ textNode :-(
e-motiv

109

ใช้insertAdjacentHTML () มันทำงานได้กับเบราว์เซอร์ปัจจุบันทั้งหมดแม้กระทั่งกับ IE11

var mylist = document.getElementById('mylist');
mylist.insertAdjacentHTML('beforeend', '<li>third</li>');
<ul id="mylist">
 <li>first</li>
 <li>second</li>
</ul>


9
ก่อนอื่นinsertAdjacentHTMLทำงานได้กับเบราว์เซอร์ทั้งหมดตั้งแต่ IE 4.0
Jonas Äppelgran

6
ประการที่สองมันยอดเยี่ยมมาก! ข้อดีอย่างมากเมื่อเทียบกับinnerHTML += ...คือการอ้างอิงถึงองค์ประกอบก่อนหน้านี้ยังคงไม่บุบสลายโดยใช้วิธีนี้
Jonas Äppelgran

7
beforebeginประการที่สามค่าที่เป็นไปได้สำหรับอาร์กิวเมนต์แรกคือ: afterbegin, beforeend, afterend, ดูบทความ MDN
Jonas Äppelgran

คำตอบที่ดีที่สุดสำหรับฉัน
Jordan

4
น่าเสียดายที่มันไม่ส่งคืน HTML ที่แทรกเป็นองค์ประกอบ
Mojimi

30

มีการใช้งาน DOM ที่ใหม่กว่าrange.createContextualFragmentซึ่งทำในสิ่งที่คุณต้องการในแนวทางที่ไม่ขึ้นกับกรอบ

มันรองรับอย่างกว้างขวาง เพื่อให้แน่ใจว่าตรวจสอบความเข้ากันได้ของมันลงในลิงค์ MDN เดียวกันเพราะมันจะมีการเปลี่ยนแปลง เมื่อวันที่พฤษภาคม 2017 นี่คือ:

Feature         Chrome   Edge   Firefox(Gecko)  Internet Explorer   Opera   Safari
Basic support   (Yes)    (Yes)  (Yes)           11                  15.0    9.1.2

3
โปรดทราบว่าสิ่งนี้มีข้อบกพร่องคล้าย ๆ กับการตั้งค่าinnerHTMLของ div องค์ประกอบบางอย่างเช่นtds จะถูกละเว้นและไม่ปรากฏในส่วนที่เป็นผลลัพธ์
Mark Amery

"มีรายงานว่าเดสก์ท็อปซาฟารีทำจุดหนึ่งสนับสนุน Range.createContextualFragment () แต่ไม่รองรับอย่างน้อยใน Safari 9.0 และ 9.1" (ลิงก์ MDN ในคำตอบ)
akauppi

27

ไม่จำเป็นต้องปรับแต่งใด ๆ คุณได้รับ API ท้องถิ่น:

const toNodes = html =>
    new DOMParser().parseFromString(html, 'text/html').body.childNodes[0]

9
สิ่งนี้ได้รับผลกระทบจากข้อเสียเปรียบหลักเช่นเดียวกับคำตอบที่ยอมรับซึ่งจะทำให้ HTML ยุ่งเหยิงเช่น<td>text</td>นั้น นี่เป็นเพราะDOMParserกำลังพยายามแยกวิเคราะห์เอกสาร HTMLแบบเต็มและองค์ประกอบทั้งหมดไม่สามารถใช้งานได้เช่นเดียวกับองค์ประกอบรากของเอกสาร
Mark Amery

4
-1 เพราะนี่เป็นคำซ้ำก่อนหน้านี้ซึ่งชี้ให้เห็นข้อเสียเปรียบที่ระบุไว้ในความคิดเห็นของฉันด้านบนอย่างชัดเจน
Mark Amery

20

สำหรับชิ้นส่วน html ที่แน่นอนเช่น<td>test</td>div.innerHTML, DOMParser.parseFromString และ range.createContextualFragment (โดยไม่มีบริบทที่เหมาะสม) โซลูชันที่กล่าวถึงในคำตอบอื่น ๆ ที่นี่จะไม่สร้าง<td>องค์ประกอบ

jQuery.parseHTML () จัดการได้อย่างถูกต้อง (ฉันแยกฟังก์ชั่น parseHTML ของ jQuery 2 ลงในฟังก์ชั่นอิสระที่สามารถใช้ในโค้ดโค้ดที่ไม่ใช่ jquery)

หากคุณสนับสนุน Edge 13+ เท่านั้นมันง่ายกว่าที่จะใช้แท็กเทมเพลต HTML5:

function parseHTML(html) {
    var t = document.createElement('template');
    t.innerHTML = html;
    return t.content.cloneNode(true);
}

var documentFragment = parseHTML('<td>Test</td>');

16

นี่เป็นวิธีง่ายๆในการทำ:

String.prototype.toDOM=function(){
  var d=document
     ,i
     ,a=d.createElement("div")
     ,b=d.createDocumentFragment();
  a.innerHTML=this;
  while(i=a.firstChild)b.appendChild(i);
  return b;
};

var foo="<img src='//placekitten.com/100/100'>foo<i>bar</i>".toDOM();
document.body.appendChild(foo);

4
@MarkAmery ความแตกต่างที่นี่ก็คือเขาใช้แฟรกเมนต์เพื่ออนุญาตให้ผนวกองค์ประกอบหลายรายการใน DOM ซึ่งเป็นประโยชน์เพิ่มเติม ถ้าวิลเลียมเท่านั้นที่พูดถึงนั่นคือคำตอบของเขา ...
โคเอ็น

10

คุณสามารถสร้างโหนด DOM ที่ถูกต้องจากสตริงโดยใช้:

document.createRange().createContextualFragment()

ตัวอย่างต่อไปนี้เพิ่มองค์ประกอบปุ่มในหน้าการทำมาร์กอัพจากสตริง:

let html = '<button type="button">Click Me!</button>';
let fragmentFromString = function (strHTML) {
  return document.createRange().createContextualFragment(strHTML);
}
let fragment = fragmentFromString(html);
document.body.appendChild(fragment);


5
แม้ว่าสิ่งนี้จะสร้างDocumentFragmentวัตถุ แต่ก็ยังเป็นเรื่องที่น่าประหลาดใจอย่างมากที่ฉันได้รับจากข้อบกพร่องเช่นเดียวกับคำตอบที่ยอมรับ: ถ้าคุณทำdocument.createRange().createContextualFragment('<td>bla</td>')คุณจะได้รับชิ้นส่วนที่ประกอบด้วยข้อความ 'bla' โดยไม่มี<td>องค์ประกอบ หรืออย่างน้อยนั่นคือสิ่งที่ฉันสังเกตเห็นใน Chrome 63 ฉันไม่ได้เจาะลึกข้อมูลจำเพาะเพื่อหาว่ามันเป็นพฤติกรรมที่ถูกต้องหรือไม่
Mark Amery

9

ด้วย Prototype คุณสามารถทำสิ่งต่อไปนี้

HTML:

<ul id="mylist"></ul>

JS:

$('mylist').insert('<li>text</li>');

jQuery นี้หรือไม่ หรือ JS
Jeya Suriya Muthumari

1
นี่คือการใช้ jQuery ไม่ใช่วิธีในตัว DOM ตามที่ระบุไว้
Juan Hurtado

1
@JuanHurtado นี่ใช้ PrototypeJs เป็น OP ขอเกือบ 11 ปีที่แล้ว;)
Pablo Borowicz

8

ฉันใช้วิธีนี้ (ใช้งานได้ใน IE9 +) แม้ว่ามันจะไม่แยกวิเคราะห์<td>หรือบางส่วนของร่างกายโดยตรงที่ไม่ถูกต้อง:

function stringToEl(string) {
    var parser = new DOMParser(),
        content = 'text/html',
        DOM = parser.parseFromString(string, content);

    // return element
    return DOM.body.childNodes[0];
}

stringToEl('<li>text</li>'); //OUTPUT: <li>text</li>

5

เพื่อปรับปรุงเพิ่มเติมตัวอย่าง. toDOM () ที่เป็นประโยชน์ที่เราสามารถหาได้ในที่ต่าง ๆ ตอนนี้เราสามารถใช้backticks ( เทมเพลตตัวอักษร ) ได้อย่างปลอดภัย

ดังนั้นเราสามารถมีคำพูดเดี่ยวและคู่ในการประกาศfoo html

สิ่งนี้ทำหน้าที่เหมือนเป็นเอกสารสำหรับผู้ที่คุ้นเคยกับคำศัพท์

สิ่งนี้สามารถปรับปรุงเพิ่มเติมพร้อมตัวแปรเพื่อสร้างเทมเพลตที่ซับซ้อน:

เทมเพลตตัวอักษรถูกล้อมรอบด้วยอักขระback-tick ( ) (สำเนียงหลุมฝังศพ) แทนเครื่องหมายคำพูดคู่หรือเดี่ยว เทมเพลตตัวอักษรสามารถมีตัวยึด สิ่งเหล่านี้ระบุด้วยเครื่องหมายดอลลาร์และเครื่องหมายปีกกา ($ {expression}) การแสดงออกในตัวยึดและข้อความระหว่างพวกเขาได้รับการส่งผ่านไปยังฟังก์ชั่น ฟังก์ชั่นเริ่มต้นเพียงแค่เชื่อมส่วนต่าง ๆ เป็นสตริงเดียว หากมีการแสดงออกก่อนหน้าเทมเพลตตัวอักษร (แท็กที่นี่) นี้เรียกว่า "เทมเพลตที่ติดแท็ก" ในกรณีดังกล่าวนิพจน์แท็ก (โดยปกติจะเป็นฟังก์ชัน) จะถูกเรียกด้วยตัวอักษรเทมเพลตที่ผ่านการประมวลผลซึ่งคุณสามารถจัดการได้ก่อนที่จะส่งออก หากต้องการหลีกเลี่ยงการย้อนกลับในตัวอักษรเทมเพลตให้ใส่เครื่องหมายแบ็กสแลช

String.prototype.toDOM=function(){
  var d=document,i
     ,a=d.createElement("div")
     ,b=d.createDocumentFragment()
  a.innerHTML = this
  while(i=a.firstChild)b.appendChild(i)
  return b
}

// Using template litterals
var a = 10, b = 5
var foo=`
<img 
  onclick="alert('The future start today!')"   
  src='//placekitten.com/100/100'>
foo${a + b}
  <i>bar</i>
    <hr>`.toDOM();
document.body.appendChild(foo);
img {cursor: crosshair}

ดังนั้นทำไมไม่ใช้โดยตรง.innerHTML +=? เมื่อทำเช่นนี้ DOM ทั้งหมดจะถูกคำนวณใหม่โดยเบราว์เซอร์จึงช้ากว่ามาก

https://caniuse.com/template-literals


4

ฉันเพิ่มDocumentต้นแบบที่สร้างองค์ประกอบจากสตริง:

Document.prototype.createElementFromString = function (str) {
    const element = new DOMParser().parseFromString(str, 'text/html');
    const child = element.documentElement.querySelector('body').firstChild;
    return child;
};

โปรดทราบว่า - ตามที่ระบุไว้ที่อื่นในหน้านี้ - สิ่งนี้จะใช้ไม่ได้กับtds
Mark Amery

3

HTML5 & ES6

<template>

การสาธิต

"use strict";

/**
 *
 * @author xgqfrms
 * @license MIT
 * @copyright xgqfrms
 * @description HTML5 Template
 * @augments
 * @example
 *
 */

/*

<template>
    <h2>Flower</h2>
    <img src="https://www.w3schools.com/tags/img_white_flower.jpg">
</template>


<template>
    <div class="myClass">I like: </div>
</template>

*/

const showContent = () => {
    // let temp = document.getElementsByTagName("template")[0],
    let temp = document.querySelector(`[data-tempalte="tempalte-img"]`),
        clone = temp.content.cloneNode(true);
    document.body.appendChild(clone);
};

const templateGenerator = (datas = [], debug = false) => {
    let result = ``;
    // let temp = document.getElementsByTagName("template")[1],
    let temp = document.querySelector(`[data-tempalte="tempalte-links"]`),
        item = temp.content.querySelector("div");
    for (let i = 0; i < datas.length; i++) {
        let a = document.importNode(item, true);
        a.textContent += datas[i];
        document.body.appendChild(a);
    }
    return result;
};

const arr = ["Audi", "BMW", "Ford", "Honda", "Jaguar", "Nissan"];

if (document.createElement("template").content) {
    console.log("YES! The browser supports the template element");
    templateGenerator(arr);
    setTimeout(() => {
        showContent();
    }, 0);
} else {
    console.error("No! The browser does not support the template element");
}
@charset "UTf-8";

/* test.css */

:root {
    --cololr: #000;
    --default-cololr: #fff;
    --new-cololr: #0f0;
}

[data-class="links"] {
    color: white;
    background-color: DodgerBlue;
    padding: 20px;
    text-align: center;
    margin: 10px;
}
<!DOCTYPE html>
<html lang="zh-Hans">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Template Test</title>
    <!--[if lt IE 9]>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.js"></script>
    <![endif]-->
</head>

<body>
    <section>
        <h1>Template Test</h1>
    </section>
    <template data-tempalte="tempalte-img">
        <h3>Flower Image</h3>
        <img src="https://www.w3schools.com/tags/img_white_flower.jpg">
    </template>
    <template data-tempalte="tempalte-links">
        <h3>links</h3>
        <div data-class="links">I like: </div>
    </template>
    <!-- js -->
</body>

</html>


2

ช้า แต่ก็เป็นโน้ต

เป็นไปได้ที่จะเพิ่มองค์ประกอบที่น่าสนใจให้กับองค์ประกอบเป้าหมายเป็นคอนเทนเนอร์และลบออกหลังจากใช้งาน

// ทดสอบบน chrome 23.0, firefox 18.0, เช่น 7-8-9 และ opera 12.11

<div id="div"></div>

<script>
window.onload = function() {
    var foo, targetElement = document.getElementById('div')
    foo = document.createElement('foo')
    foo.innerHTML = '<a href="#" target="_self">Text of A 1.</a> '+
                    '<a href="#" onclick="return !!alert(this.innerHTML)">Text of <b>A 2</b>.</a> '+
                    '<hr size="1" />'
    // Append 'foo' element to target element
    targetElement.appendChild(foo)

    // Add event
    foo.firstChild.onclick = function() { return !!alert(this.target) }

    while (foo.firstChild) {
        // Also removes child nodes from 'foo'
        targetElement.insertBefore(foo.firstChild, foo)
    }
    // Remove 'foo' element from target element
    targetElement.removeChild(foo)
}
</script>

2

โซลูชันที่เร็วที่สุดในการเรนเดอร์ DOM จากสตริง:

let render = (relEl, tpl, parse = true) => {
  if (!relEl) return;
  const range = document.createRange();
  range.selectNode(relEl);
  const child = range.createContextualFragment(tpl);
  return parse ? relEl.appendChild(child) : {relEl, el};
};

และที่นี่คุณสามารถตรวจสอบประสิทธิภาพสำหรับ DOM การจัดการ React vs native JS

ตอนนี้คุณสามารถใช้:

let element = render(document.body, `
<div style="font-size:120%;line-height:140%">
  <p class="bold">New DOM</p>
</div>
`);

และแน่นอนในอนาคตอันใกล้คุณใช้การอ้างอิงจากหน่วยความจำทำให้ var "element" เป็น DOM ที่คุณสร้างขึ้นใหม่ในเอกสารของคุณ

และจำไว้ว่า "innerHTML =" ช้ามาก: /


1

นี่คือรหัสของฉันและใช้งานได้:

function parseTableHtml(s) { // s is string
    var div = document.createElement('table');
    div.innerHTML = s;

    var tr = div.getElementsByTagName('tr');
    // ...
}

1
ล้มเหลวหากองค์ประกอบที่จะสร้างเป็นตารางตัวเอง
Mark Amery

0

สำหรับความหายนะของมันฉันคิดว่าฉันจะแบ่งปันสิ่งนี้มากกว่าวิธีที่ซับซ้อน แต่ยังง่ายฉันมากับ ... บางทีใครบางคนอาจจะพบบางสิ่งที่มีประโยชน์

/*Creates a new element - By Jamin Szczesny*/
function _new(args){
    ele = document.createElement(args.node);
    delete args.node;
    for(x in args){ 
        if(typeof ele[x]==='string'){
            ele[x] = args[x];
        }else{
            ele.setAttribute(x, args[x]);
        }
    }
    return ele;
}

/*You would 'simply' use it like this*/

$('body')[0].appendChild(_new({
    node:'div',
    id:'my-div',
    style:'position:absolute; left:100px; top:100px;'+
          'width:100px; height:100px; border:2px solid red;'+
          'cursor:pointer; background-color:HoneyDew',
    innerHTML:'My newly created div element!',
    value:'for example only',
    onclick:"alert('yay')"
}));

0

ทำไมไม่ทำกับ js พื้นเมือง?

    var s="<span class='text-muted' style='font-size:.75em; position:absolute; bottom:3px; left:30px'>From <strong>Dan's Tools</strong></span>"
    var e=document.createElement('div')
    var r=document.createRange();
    r.selectNodeContents(e)
    var f=range.createContextualFragment(s);
    e.appendChild(f);
    e = e.firstElementChild;

-1
function domify (str) {
  var el = document.createElement('div');
  el.innerHTML = str;

  var frag = document.createDocumentFragment();
  return frag.appendChild(el.removeChild(el.firstChild));
}

var str = "<div class='foo'>foo</div>";
domify(str);

-2

คุณสามารถใช้ฟังก์ชันต่อไปนี้เพื่อแปลงข้อความ "HTML" เป็นองค์ประกอบ

function htmlToElement(html)
{
  var element = document.createElement('div');
  element.innerHTML = html;
  return(element);
}
var html="<li>text and html</li>";
var e=htmlToElement(html);


-1; นี่เป็นเทคนิคเดียวกับที่เสนอในคำตอบที่ยอมรับและมีข้อเสียเปรียบเดียวกัน - โดยเฉพาะไม่ทำงานสำหรับtds
Mark Amery


-3

นี่คือรหัสที่ใช้งานได้สำหรับฉัน

ฉันต้องการแปลงสตริง ' ข้อความ ' เป็นองค์ประกอบ HTML

var diva = UWA.createElement('div');
diva.innerHTML = '<a href="http://wwww.example.com">Text</a>';
var aelement = diva.firstChild;

คือwwwwอะไร
Tintin81

-3

var msg = "ทดสอบ" jQuery.parseHTML (msg)


ขอขอบคุณสำหรับข้อมูลโค้ดนี้ซึ่งอาจให้ความช่วยเหลือแบบ จำกัด และทันที คำอธิบายที่เหมาะสมมากจะเพิ่มมูลค่าในระยะยาวด้วยการแสดงเหตุผลนี้เป็นทางออกที่ดีในการแก้ไขปัญหาและจะทำให้มันมีประโยชน์มากขึ้นให้กับผู้อ่านในอนาคตกับอื่น ๆ คำถามที่คล้ายกัน โปรดแก้ไขคำตอบของคุณเพื่อเพิ่มคำอธิบายรวมถึงข้อสมมติฐานที่คุณทำ
Dwhitz

-7

สิ่งนี้จะใช้ได้เช่นกัน:

$('<li>').text('hello').appendTo('#mylist');

รู้สึกเหมือน jquery มากขึ้นด้วยการเรียกฟังก์ชั่นที่ถูกล่ามโซ่


26
รู้สึกเหมือน jQuery เพราะเป็น jQuery หรือไม่
Tim Ferrell

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