รับการแสดงสตริงของโหนด DOM


99

Javascript: ฉันมีการแสดง DOM ของโหนด (องค์ประกอบหรือเอกสาร) และฉันกำลังมองหาการแสดงสตริงของมัน เช่น,

var el = document.createElement("p");
el.appendChild(document.createTextNode("Test"));

ควรให้ผล:

get_string(el) == "<p>Test</p>";

ฉันมีความรู้สึกที่ดีว่าฉันพลาดอะไรง่ายๆไปเล็กน้อย แต่ฉันไม่พบวิธีที่ใช้ได้กับ IE, FF, Safari และ Opera ดังนั้น outerHTML จึงไม่มีตัวเลือก


4
โดยสันนิษฐานว่าเวอร์ชัน 11 Firefox ยังรองรับ outerHTML: bugzilla.mozilla.org/show_bug.cgi?id=92264
Boldewyn

1
สำหรับตอนนี้ดูเหมือนว่า IE, FF, Safari, Chrome, Opera ทั้งหมดรองรับ outerHTML ดูdeveloper.mozilla.org/en-US/docs/Web/API/Element/outerHTML
wangf

1
ใช่ตอนนี้ (ตั้งแต่ปี 2009 นั่นคือ) กลายเป็นงานที่ไม่สำคัญ :)
Boldewyn

ใช่แน่นอน outerHTML
neaumusic

คำตอบ:


138

คุณสามารถสร้างโหนดแม่ชั่วคราวและรับเนื้อหา innerHTML ของมันได้:

var el = document.createElement("p");
el.appendChild(document.createTextNode("Test"));

var tmp = document.createElement("div");
tmp.appendChild(el);
console.log(tmp.innerHTML); // <p>Test</p>

แก้ไข: โปรดดูคำตอบด้านล่างเกี่ยวกับ outerHTML el.outerHTML ควรเป็นสิ่งที่จำเป็นทั้งหมด


1
อุ๊ย. ง่ายมาก ... หมายเหตุเพียงเล็กน้อย: หากฉันต้องการให้ทั้งเอกสาร "เข้มงวด" ฉันสามารถใช้วิธีการเดียวกันกับ document.documentElement (usecase: AJAX request) บางทีคุณอาจรวมสิ่งนั้นไว้ในคำตอบ?
Boldewyn

3
@Boldewyn: คุณสามารถต่อท้ายทั้งหมดdocument.documentElementเป็น div ได้หรือไม่? Holy crap ....
Roatin Marth

ง่ายเหมือนนรก ... +1 เอกสารแย่เกินไป Fragment ไม่รองรับ innerHTML
Lajos Meszaros

30
outerHTML คือคำตอบ
neaumusic

3
อย่าลืมให้โคลนของคุณelementก่อนที่จะเพิ่มtmpbecouse เมื่อคุณเพิ่มเข้าไปก็จะถูกลบออกจากtmp document
Olcay Ertaş

46

สิ่งที่คุณกำลังมองหาคือ 'outerHTML' แต่วีต้องการทางเลือกเพราะมันไม่สามารถใช้งานร่วมกับเบราว์เซอร์รุ่นเก่าได้

var getString = (function() {
  var DIV = document.createElement("div");

  if ('outerHTML' in DIV)
    return function(node) {
      return node.outerHTML;
    };

  return function(node) {
    var div = DIV.cloneNode();
    div.appendChild(node.cloneNode(true));
    return div.innerHTML;
  };

})();

// getString(el) == "<p>Test</p>"

คุณจะพบปลั๊กอิน jQuery ของฉันที่นี่: รับ HTML ภายนอกขององค์ประกอบที่เลือก


Firefox เพิ่มouterHTMLในเวอร์ชัน 11 หลังจากที่ฉันถามคำถาม นั่นไม่ใช่ทางเลือกในตอนนั้น ฉันได้อัปเดตคำถามของฉันด้วยความคิดเห็นที่เหมาะสมหากคุณดูแลอย่างใกล้ชิด
Boldewyn

นี่คือสิ่งที่ถูกต้องเพราะคุณทิ้งรหัสองค์ประกอบและองค์ประกอบอื่น ๆ หากใช้innerHtml
Sergei Panfilov

1
@SergeyPanfilov: ฉันไม่ได้ทำอะไรหล่นเพราะฉันห่อโหนดไว้ใน div ว่างก่อนโทรinnerHTML; )
gtournie

3
ในปี 2558 ฉันจะบอกว่านี่เป็นคำตอบที่ดีที่สุด
ACK_stoverflow

ใช่ ณ วันนี้เฉพาะที่เก่ามาก (IE> 10, Safari> 7, FF, Chrome โบราณอย่างแท้จริง) และ / หรือเบราว์เซอร์ที่ไม่ชัดเจน (Opera Mini) ไม่รองรับouterHTMLแอตทริบิวต์ ดูcaniuse.com/#feat=xml-serializer
Gert Sønderโดย

20

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

get_string=(el)=>el.outerHTML;

นี่คือคำตอบที่ดีที่สุด
Avraham

15

ภายใต้ FF คุณสามารถใช้XMLSerializerวัตถุเพื่อทำให้เป็นอนุกรม XML เป็นสตริง IE ให้xmlคุณสมบัติของโหนดแก่คุณ คุณสามารถทำสิ่งต่อไปนี้ได้:

function xml2string(node) {
   if (typeof(XMLSerializer) !== 'undefined') {
      var serializer = new XMLSerializer();
      return serializer.serializeToString(node);
   } else if (node.xml) {
      return node.xml;
   }
}

FYI .xmlไม่ทำงานบนโหนด DOM (เช่นเดียวกับในโหนดในหน้าปัจจุบัน) ใช้ได้กับโหนดเอกสาร XML DOM เท่านั้น
Crescent Fresh

และในทางกลับกันouterHTMLไม่ทำงานกับโหนดเอกสาร XML DOM ใช้ได้กับโหนด DOM เท่านั้น (เช่นเดียวกับในโหนดในเพจปัจจุบัน) ฉันจะบอกว่ามีความสม่ำเสมอดี
Crescent Fresh

7

ใช้ Element # outerHTML:

var el = document.createElement("p");
el.appendChild(document.createTextNode("Test"));

console.log(el.outerHTML);

นอกจากนี้ยังสามารถใช้เพื่อเขียนองค์ประกอบ DOM จากเอกสารของ Mozilla:

แอ็ตทริบิวต์ outerHTML ของอินเทอร์เฟซ DOM ของอิลิเมนต์ได้รับแฟรกเมนต์ HTML ที่ต่อเนื่องซึ่งอธิบายองค์ประกอบรวมถึงลูกหลาน สามารถตั้งค่าให้แทนที่องค์ประกอบด้วยโหนดที่แยกวิเคราะห์จากสตริงที่กำหนด

https://developer.mozilla.org/en-US/docs/Web/API/Element/outerHTML


3

ใช้ element.outerHTML เพื่อแสดงองค์ประกอบทั้งหมดรวมถึงแท็กภายนอกและแอตทริบิวต์


1

หากองค์ประกอบของคุณมีพาเรนต์

element.parentElement.innerHTML

2
ขอบคุณสำหรับคำตอบ! น่าเสียดายที่ได้แนะนำไปแล้ว แต่ผู้ตอบลบคำตอบ ปัญหาคือว่าพ่อแม่อาจจะมีเป็นจำนวนมากมากขึ้นมาร์กอัปกว่าต้องการ ลองนึกถึง outerHTML สำหรับรายการเดียว<li>ในรายการ
Boldewyn

1

ลอง

new XMLSerializer().serializeToString(element);

ขอบคุณสำหรับคำแนะนำ แต่นั่นคือสิ่งที่ไบรอันเคลแนะนำในคำตอบของเขา
Boldewyn

1

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

นี่คือฟังก์ชั่น (ทดสอบขั้นต่ำใน Chrome):

/**
 * Stringifies a DOM node.
 * @param {Object} el - A DOM node.
 * @param {Number} truncate - How much to truncate innerHTML of element.
 * @returns {String} - A stringified node with attributes
 *                     retained.
 */
function stringifyEl(el, truncate) {
    var truncateLen = truncate || 50;
    var outerHTML = el.outerHTML;
    var ret = outerHTML;
    ret = ret.substring(0, truncateLen);

    // If we've truncated, add an elipsis.
    if (outerHTML.length > truncateLen) {
      ret += "...";
    }
    return ret;
}

https://gist.github.com/kahunacohen/467f5cc259b5d4a85eb201518dcb15ec


0

ฉันเสียเวลาไปมากในการค้นหาว่ามีอะไรผิดปกติเมื่อฉันทำซ้ำผ่าน DOMElements ด้วยรหัสในคำตอบที่ยอมรับ นี่คือสิ่งที่ใช้ได้ผลสำหรับฉันมิฉะนั้นทุกองค์ประกอบที่สองจะหายไปจากเอกสาร:

_getGpxString: function(node) {
          clone = node.cloneNode(true);
          var tmp = document.createElement("div");
          tmp.appendChild(clone);
          return tmp.innerHTML;
        },

1
ฉันไม่ได้ออกไปข้างนอกเมื่อฉันคิดว่าคุณมีปัญหาอื่นที่นี่ โปรดทราบว่าโซลูชันข้างต้นจะลบองค์ประกอบดั้งเดิมออกจาก DOM ดังนั้นเมื่อคุณใช้คอลเลกชันสดเช่นdocument.getElementsByTagName()คอลเลกชันนั้นจะเปลี่ยนไปในช่วงกลาง - forลูปดังนั้นการข้ามองค์ประกอบทุกวินาที
Boldewyn

-1

ถ้าใช้ react:

const html = ReactDOM.findDOMNode(document.getElementsByTagName('html')[0]).outerHTML;

.outerHTMLไม่เฉพาะการตอบสนอง เป็นมาตรฐาน DOM ตรวจสอบคำตอบของ @Rich Apodaca
chharvey

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