Nhận biểu diễn chuỗi của một nút DOM


96

Javascript: Tôi có biểu diễn DOM của một nút (phần tử hoặc tài liệu) và tôi đang tìm kiếm biểu diễn chuỗi của nó. Ví dụ,

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

nên nhường:

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

Tôi có cảm giác mạnh mẽ, rằng tôi đang thiếu một thứ gì đó đơn giản đến mức tầm thường, nhưng tôi không tìm thấy một phương pháp nào hoạt động trong IE, FF, Safari và Opera. Do đó, externalHTML không phải là tùy chọn.


4
Có lẽ với phiên bản 11, Firefox cũng hỗ trợ ngoàiHTML: bugzilla.mozilla.org/show_bug.cgi?id=92264
Boldewyn

1
Hiện tại, có vẻ như IE, FF, Safari, Chrome, Opera đều hỗ trợ ngoàiHTML, hãy xem developer.mozilla.org/en-US/docs/Web/API/Element/outerHTML
wangf

1
Vâng, nó có bây giờ (từ năm 2009), cũng được trở thành một nhiệm vụ tầm thường :)
Boldewyn

Yea, chắc chắn outerHTML
neaumusic

Câu trả lời:


133

Bạn có thể tạo một nút cha tạm thời và lấy nội dung InternalHTML của nó:

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>

CHỈNH SỬA: Vui lòng xem câu trả lời bên dưới về ngoàiHTML. el.outerHTML phải là tất cả những gì cần thiết.


1
Ôi chao. Rất đơn giản ... Chỉ cần một lưu ý nhỏ: Nếu tôi muốn toàn bộ tài liệu "được xâu chuỗi", tôi có thể sử dụng cùng một phương pháp với document.documentElement (usecase: AJAX Request). Có lẽ bạn có thể kết hợp điều đó trong câu trả lời?
Boldewyn

3
@Boldewyn: bạn có thể nối toàn bộ document.documentElementvào một div không? Thánh tào lao ....
Roatin Marth

Đơn giản, như là địa ngục ... 1 Quá xấu documentFragment không hỗ trợ innerHTML
Lajos Mészáros

30
outerHTML là câu trả lời
neaumusic

3
Đừng quên sao chép của bạn elementtrước khi thêm nó tmpvì khi bạn thêm nó vào tmp, nó sẽ bị xóa khỏi document.
Olcay Ertaş

44

Những gì bạn đang tìm kiếm là 'ngoàiHTML', nhưng cần một dự phòng vì nó không tương thích với các trình duyệt cũ.

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>"

Bạn sẽ tìm thấy plugin jQuery của tôi ở đây: Lấy HTML bên ngoài của phần tử đã chọn


Firefox đã thêm outerHTMLvào phiên bản 11, sau khi tôi đặt câu hỏi. Vì vậy, đó không phải là một lựa chọn hồi đó. Tôi thậm chí đã cập nhật câu hỏi của mình với một bình luận thích hợp, nếu bạn nhìn kỹ.
Boldewyn

Đúng vậy, bạn bỏ id phần tử và các phần đính kèm khác nếu sử dụnginnerHtml
Sergei Panfilov

1
@SergeyPanfilov: Tôi không làm rơi bất cứ thứ gì vì tôi đã bọc nút trong một div trống trước khi gọi innerHTML; )
gtournie

3
Vào năm 2015, tôi sẽ nói rằng đây là câu trả lời xa vời và xa vời nhất.
ACK_stoverflow

Vâng, cho đến ngày nay, chỉ có các trình duyệt rất cũ (IE> 10, Safari> 7, FF thực sự cổ xưa, Chrome) và / hoặc các trình duyệt khó hiểu (Opera Mini) không hỗ trợ outerHTMLthuộc tính này. Xem thêm caniuse.com/#feat=xml-serializer
Gert Sønderby

20

Tôi không nghĩ rằng bạn cần bất kỳ kịch bản phức tạp nào cho việc này. Chỉ dùng

get_string=(el)=>el.outerHTML;

đây là câu trả lời hay nhất
Avraham

15

Trong FF, bạn có thể sử dụng XMLSerializerđối tượng để tuần tự hóa XML thành một chuỗi. IE cung cấp cho bạn một xmlthuộc tính của một nút. Vì vậy, bạn có thể làm như sau:

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

FYI .xmlkhông hoạt động trên các nút DOM (như trong các nút trong trang hiện tại). Nó chỉ hoạt động trên các nút tài liệu DOM XML.
Crescent Fresh

Và ngược lại, outerHTMLkhông hoạt động trên các nút tài liệu DOM XML. Nó chỉ hoạt động trên các nút DOM (như trong các nút trong trang hiện tại). Tôi muốn nói rằng có sự nhất quán tốt.
Crescent Fresh

7

Sử dụng Phần tử # ngoàiHTML:

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

console.log(el.outerHTML);

Nó cũng có thể được sử dụng để viết các phần tử DOM. Từ tài liệu của Mozilla:

Thuộc tính externalHTML của giao diện DOM phần tử nhận phân đoạn HTML được tuần tự hóa mô tả phần tử bao gồm các phần tử con của nó. Nó có thể được đặt để thay thế phần tử bằng các nút được phân tích cú pháp từ chuỗi đã cho.

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


3

Sử dụng element.outerHTML để có được sự trình bày đầy đủ của phần tử, bao gồm các thẻ và thuộc tính bên ngoài.


1

Nếu phần tử của bạn có cha mẹ

element.parentElement.innerHTML

2
Cảm ơn vì câu trả lời! Rất tiếc, câu trả lời đã được gợi ý, nhưng người trả lời đã xóa câu trả lời. Vấn đề là, rằng phụ huynh có thể chứa nhiều hơn đánh dấu hơn mong muốn. Hãy nghĩ đến ngoàiHTML cho một thẻ duy nhất <li>trong danh sách.
Boldewyn

1

Thử

new XMLSerializer().serializeToString(element);

Cảm ơn vì gợi ý, nhưng đó chính xác là những gì Bryan Kale đề xuất trong câu trả lời của mình.
Boldewyn

1

Tôi nhận thấy rằng đối với các trường hợp sử dụng của mình, tôi không phải lúc nào cũng muốn toàn bộ bên ngoàiHTML. Nhiều nút có quá nhiều nút con để hiển thị.

Đây là một chức năng (được thử nghiệm tối thiểu trong 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

Tôi đã lãng phí rất nhiều thời gian để tìm ra vấn đề gì xảy ra khi tôi lặp qua DOMElements với mã trong câu trả lời được chấp nhận. Đây là những gì đã làm việc cho tôi, nếu không mọi phần tử thứ hai sẽ biến mất khỏi tài liệu:

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

1
Tôi không đi ra ngoài, khi tôi cho rằng bạn có một vấn đề khác ở đây. Lưu ý rằng giải pháp trên sẽ xóa phần tử gốc khỏi DOM. Vì vậy, khi bạn sử dụng một bộ sưu tập trực tiếp như vậy document.getElementsByTagName(), bộ sưu tập đó sẽ thay đổi giữa forvòng, do đó sẽ bỏ qua mỗi phần tử thứ hai.
Boldewyn

-1

nếu sử dụng react:

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

.outerHTMLkhông dành riêng cho React; nó là một tiêu chuẩn DOM. Kiểm tra câu trả lời của @Rich Apodaca.
chharvey

vâng ... điểm quan tâm (nếu sử dụng react) trong câu trả lời của tôi là reactdom.findDOMNode()..., không phải .outerHTML, mà là cảm ơn về vị trí.
eatorkurauchi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.