将 HTML 字符串转换为 DOM 元素?

Posted

技术标签:

【中文标题】将 HTML 字符串转换为 DOM 元素?【英文标题】:Converting HTML string into DOM elements? 【发布时间】:2011-03-07 10:43:34 【问题描述】:

有没有办法像这样转换 html

<div>
<a href="#"></a>
<span></span>
</div>

或任何其他 HTML 字符串到 DOM 元素中? (这样我就可以使用 appendChild())。我知道我可以使用 .innerHTML 和 .innerText,但这不是我想要的——我确实希望能够将动态 HTML 字符串转换为 DOM 元素,以便可以在 .appendChild() 中传递它。

更新:似乎有些混乱。我有一个字符串中的 HTML 内容,作为 javascript 中变量的值。文档中没有 HTML 内容。

【问题讨论】:

看看这个:***.com/questions/494143/… 如果你想要更接近 HTML 而不是节点,我建议使用以下函数 ;) ` var stringToHTML = function (str) var dom = document.createElement('div'); dom.innerHTML = str;返回 dom; ; ` 【参考方案1】:

您可以使用DOMParser,如下所示:

var xmlString = "<div id='foo'><a href='#'>Link</a><span></span></div>";
var doc = new DOMParser().parseFromString(xmlString, "text/xml");
console.log(doc.firstChild.innerHTML); // => <a href="#">Link...
console.log(doc.firstChild.firstChild.innerHTML); // => Link

【讨论】:

谢谢,效果很好。在阅读了 Mozilla 的文章后,我意识到浏览器也可以解析 XML AJAX 响应——所以像 IE 这样不支持 DOMParser 的浏览器,我使用带有数据 URI 的同步 AJAX 调用来解析 XML。 :) 如果您因为尝试加载 HTML 而不是像 标签那样的 XML 而出现错误,请查看此处:developer.mozilla.org/en-US/docs/DOM/DOMParser在“DOMParser HTML extension for other browsers”下支持加载 HTML @maerics 为什么不能直接说text/html 来解析HTML? @Djack 可以,但是会自动生成“html”和“body”标签。 注意:如果将创建的节点放回浏览器的 DOM (Safari 9.1.2),我发现使用“text/html”而不是“text/xml”至关重要。否则,CSS 渲染将无法正常工作。如果您使用它,请使用“.body”绕过自动插入的正文元素。【参考方案2】:

您通常会创建一个临时父元素,您可以在其中写入innerHTML,然后提取内容:

var wrapper= document.createElement('div');
wrapper.innerHTML= '<div><a href="#"></a><span></span></div>';
var div= wrapper.firstChild;

如果你得到的外部 HTML 元素是一个简单的&lt;div&gt;,就像这里一样,这很容易。如果它可能是其他任何地方都无法解决的问题,那么您可能会遇到更多问题。例如,如果它是 &lt;li&gt;,则必须将父包装器设为 &lt;ul&gt;

但是 IE 不能在像 &lt;tr&gt; 这样的元素上写 innerHTML 所以如果你有一个 &lt;td&gt; 你必须把整个 HTML 字符串包装在 &lt;table&gt;&lt;tbody&gt;&lt;tr&gt;...&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; 中,写 那个innerHTML,然后将你想要的实际&lt;td&gt;从几个层次中解脱出来。

【讨论】:

+1 这个解决方案可能更便携。 请记住,此方法将丢失任何事件处理程序或预先分配给它的其他属性。 @bryc 字符串如何附加事件处理程序/ @Muhammad - 或许可以使用 onclick="..." 之类的东西,尽管这对于 HTML 中未定义的事件处理程序当然不起作用,这可能就是您的意思。 如果字符串是这样的some string at the start &lt;div&gt;&lt;a href="#"&gt;anchor text&lt;/a&gt;&lt;span&gt;inner text&lt;/span&gt;&lt;/div&gt;string end怎么办?【参考方案3】:

为什么不使用insertAdjacentHTML

例如:

// <div id="one">one</div> 
var d1 = document.getElementById('one'); 
d1.insertAdjacentHTML('afterend', '<div id="two">two</div>');

// At this point, the new structure is:
// <div id="one">one</div><div id="two">two</div>here

【讨论】:

在链接中有一个例子 - 但我也复制粘贴在这里 您知道您应该将此元素放在 DOM 中以使其正常工作吗?并且您实际上并不希望在 DOM 中使用此元素,您只想将字符串转换为 HTML 在内存中【参考方案4】:

查看 John Resig 的 pure JavaScript HTML parser。

编辑:如果您希望浏览器为您解析 HTML,innerHTML 正是您想要的。来自this SO question:

var tempDiv = document.createElement('div');
tempDiv.innerHTML = htmlString;

【讨论】:

在编写示例时,我注意到简单的 HTML 标记可以正确呈现(在 IE7 上),但是当我尝试使用脚本(我正在处理的情况)时,脚本不会工作。示例:Fiddle。您可能必须在本地 html 页面上运行代码(jsfiddle 不适用于 IE7)。 这段代码有一个小问题:如果htmlString喜欢&lt;tr&gt;...&lt;/tr&gt;,它就不能正常工作:(【参考方案5】:

好吧,在我不得不考虑其他人的答案之后,我自己意识到了答案。 :P

var htmlContent = ... // a response via AJAX containing HTML
var e = document.createElement('div');
e.setAttribute('style', 'display: none;');
e.innerHTML = htmlContent;
document.body.appendChild(e);
var htmlConvertedIntoDom = e.lastChild.childNodes; // the HTML converted into a DOM element :), now let's remove the
document.body.removeChild(e);

【讨论】:

您不需要在文档中添加“e”。您也不需要对其执行 setAttribute 。【参考方案6】:

这是一个有用的小代码。

var uiHelper = function () 

var htmls = ;

var getHTML = function (url) 
                /// <summary>Returns HTML in a string format</summary>
                /// <param name="url" type="string">The url to the file with the HTML</param>

    if (!htmls[url])
    
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.open("GET", url, false);
    xmlhttp.send();
    htmls[url] = xmlhttp.responseText;
     ;
     return htmls[url];
    ;

        return 
            getHTML: getHTML
        ;
();

--将HTML字符串转化为DOM元素

String.prototype.toDomElement = function () 

        var wrapper = document.createElement('div');
        wrapper.innerHTML = this;
        var df= document.createDocumentFragment();
        return df.addChilds(wrapper.children);
;

--原型助手

HTMLElement.prototype.addChilds = function (newChilds) 
        /// <summary>Add an array of child elements</summary>
        /// <param name="newChilds" type="Array">Array of HTMLElements to add to this HTMLElement</param>
        /// <returns type="this" />
        for (var i = 0; i < newChilds.length; i += 1)  this.appendChild(newChilds[i]); ;
        return this;
;

--用法

 thatHTML = uiHelper.getHTML('/Scripts/elevation/ui/add/html/add.txt').toDomElement();

【讨论】:

Uhhh... 这基本上只是@orip 的答案,但除了扩展原生StringHTMLElement 原型之外,还添加了许多完全不必要的东西(你通常真的不应该这样做)不会)。这是无关紧要的危险...... @aendrew 这是不同的例子。原型助手恰好是我在整个解决方案中获得的最佳助手之一,我传入了一个 DOM 元素数组 [ele,ele,ele,ele,ele],所以我不敢苟同。而且,第一次转换为 DOM 元素也很棒。了解有关 DocumentFragment 的更多信息,“没有人使用过”,您就会看到发生了什么。这些是助手,在一个 util 文件中。这就是当今世界开发人员的问题所在,如果不是第 3 方,他们将一无所知。我从头开始编写我所有的 JS。 并且扩展我的最后评论,在我的大多数 JS 应用程序中都非常重视性能。 我只是说不要污染内置函数的原型。如今,这被认为是最佳实践,与从头开始编写 JS、使用库或性能完全无关——它是为了防止进一步出现错误。【参考方案7】:

只需给元素一个id 并正常处理它,例如:

<div id="dv">
<a href="#"></a>
<span></span>
</div>

现在你可以这样做了:

var div = document.getElementById('dv');
div.appendChild(......);

或者使用 jQuery:

$('#dv').get(0).appendChild(........);

【讨论】:

这是您提供的一个 jQuery 示例。我认为@rFactor 正在寻找更直接的 Javascript 示例。 @clarke78:在否决投票之前,您应该已经看到我已经给出了一个纯 JavaScript 的示例。 该示例不起作用,因为它适用于已经存在的 DOM 元素。当然,如果元素已经是 DOM 元素,情况很简单,但在我的情况下,HTML 内容是变量的值,而不是 DOM 的一部分。 @rFactor - 你愿意/能够使用 jQuery 吗?如果可以使用的话,将一串 HTML 解析成 DOM 元素是非常简单的 我没有使用 jQuery,但是 jQuery 可以做的任何事情都可以用纯 JavaScript 完成,所以,如果你有任何例子,请告诉我。嗯,实际上我想我自己找到了答案。 :P【参考方案8】:

你可以这样做:

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);

【讨论】:

以上是关于将 HTML 字符串转换为 DOM 元素?的主要内容,如果未能解决你的问题,请参考以下文章

将HTML字符转换为DOM并动态添加到页面

XML文件和DOM DocumentString字符串三种类型之间的相互转换

网页中DOM元素转换成图片

js字符串每个数组前面数字转换为多少个数组

将 jQuery 选择器转换为 HTML 以获取新的 DOM 元素

20170407-dom对象(转)