获取DOM节点的字符串表示形式


96

Javascript:我有一个节点(元素或文档)的DOM表示形式,并且正在寻找它的字符串表示形式。例如,

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

应该产生:

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

我有一种强烈的感觉,我错过了一些简单的事情,但是我只是找不到一种可以在IE,FF,Safari和Opera中使用的方法。因此,outerHTML是没有选择的。


4
Firefox的版本大概为11,它也支持
externalHTML

1
就目前而言,IE,FF,Safari,Chrome,Opera都支持outerHTML,请参阅developer.mozilla.org/en-US/docs/Web/API/Element/outerHTML
wangf 2015年

1
是的,它现在(自2009年以来)已经变得不那么重要了:)
Boldewyn

是的,绝对是
externalHTML

Answers:


133

您可以创建一个临时父节点,并获取它的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>

编辑: 请参阅以下有关externalHTML的答案。el.outerHTML应该是所需要的。


1
哎哟。如此简单...仅需注意一点:如果我想要整个文档“字符串化”,则可以对document.documentElement使用相同的方法(用例:AJAX请求)。也许您可以将其纳入答案?
Boldewyn

3
@Boldewyn:您可以将整个追加document.documentElement到div中吗?哇靠...
Roatin马斯

很简单,地狱... +1糟糕的documentFragment不支持innerHTML
Lajos Meszaros 2013年


3
别忘了element先将其克隆,再将其tmp添加到tmp,因为它将被从中删除document
OlcayErtaş16年

44

您正在寻找的是“ 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


outerHTML在我提出问题后,Firefox 在版本11中进行了添加。所以那不是当时的选择。如果您仔细观察的话,我什至还用适当的评论更新了我的问题。
Boldewyn

此权利,因为您使用,请删除元素ID和其他属性innerHtml
Sergei Panfilov

1
@SergeyPanfilov:我没有删除任何东西,因为在调用之前我将节点包装在一个空的div中innerHTML;)
gtournie

3
在2015年,我会说这是最好的答案。
ACK_stoverflow

是的,到目前为止,只有非常老的(IE> 10,Safari> 7,真正的古代FF,Chrome)和/或晦涩的浏览器(Opera Mini)不支持该outerHTML属性。另见caniuse.com/#feat=xml-serializer
格特Sønderby

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文档节点。

相反,outerHTML不适用于XML DOM文档节点。它仅适用于DOM节点(如当前页面中的节点)。我会说那里的一致性很好。

7

使用Element#outerHTML:

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

console.log(el.outerHTML);

它也可以用来编写DOM元素。从Mozilla的文档中:

元素DOM接口的externalHTML属性获取描述元素(包括其后代)的序列化HTML片段。可以设置为将元素替换为从给定字符串解析的节点。

https://developer.mozilla.org/zh-CN/docs/Web/API/Element/outerHTML



1

如果您的元素具有父元素

element.parentElement.innerHTML

2
感谢你的回答!不幸的是,这已经被建议了,但是应答者删除了答案。问题是,父可能含有大量的标记比通缉。想一想outerHTML <li>就是列表中的一个。
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 2014年

-1

如果使用react:

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

.outerHTML不是特定于React的;这是DOM标准。查看@Rich Apodaca的答案。
chharvey

是的...我的回答的关注点(如果使用react)是reactdom.findDOMNode()...,不是.outerHTML,但感谢您的职位。
victorkurauchi
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.