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

Converting HTML string into DOM elements?

提问人:Tower 提问时间:6/24/2010 最后编辑:DeduplicatorTower 更新时间:6/22/2023 访问量:588200

问:

有没有办法转换 HTML,例如:

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

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

更新:似乎存在混淆。我将 HTML 内容放在一个字符串中,作为 JavaScript 中变量的值。文档中没有 HTML 内容。

JavaScript HTML DOM

评论

7赞 jhleath 6/24/2010
看看这个: stackoverflow.com/questions/494143/...
0赞 La pach' 7/28/2021
如果你想要更接近的 HTML 而不是 node,我建议使用以下函数 ;) ' var stringToHTML = function (str) { var dom = document.createElement('div'); dom.innerHTML = str; return dom; };`

答:

1赞 Sarfraz 6/24/2010 #1

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

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

现在你可以做这样的事情:

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

或者使用 jQuery:

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

评论

0赞 darcy 6/24/2010
这是您给出的 jQuery 示例。我认为@rFactor正在寻找一个更直接的 Javascript 示例。
3赞 Sarfraz 6/24/2010
@clarke78:在投反对票之前,你应该已经看到我已经给出了一个纯javascript的例子。
2赞 Tower 6/24/2010
该示例不起作用,因为它适用于已存在的 DOM 元素。当然,如果元素已经是 DOM 元素,情况很简单,但在我的情况下,HTML 内容是变量的值,而不是 DOM 的一部分。
0赞 John Rasch 6/24/2010
@rFactor - 您是否愿意/能够使用jQuery?如果可以的话,将 HTML 字符串解析为 DOM 元素非常简单
0赞 Tower 6/24/2010
我没有使用jQuery,但是jQuery可以做的任何事情都可以用纯JavaScript完成,所以,如果您有任何示例,请告诉我。嗯,其实我想我自己找到了答案。:P
17赞 orip 6/24/2010 #2

查看 John Resig 的纯 JavaScript HTML 解析器

编辑:如果您希望浏览器为您解析HTML,这正是您想要的。从这个 SO 问题innerHTML

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

评论

0赞 Yuval 4/13/2014
在编写示例时,我注意到简单的 HTML 标记可以正确呈现(在 IE7 上),但是当我尝试使用脚本来执行此操作时,我正在处理的情况是,脚本不起作用。示例:小提琴。您可能需要在本地 html 页面上运行代码(jsfiddle 在 IE7 中效果不佳)。
0赞 Aikon Mogwai 6/6/2019
此代码有一个小问题:如果喜欢:(,它无法正常工作htmlString<tr>...</tr>
509赞 maerics 6/24/2010 #3

你可以像这样使用 ,如下所示: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

评论

3赞 Tower 6/24/2010
谢谢,效果很好。在阅读了Mozilla的文章后,我意识到浏览器也可以解析XML AJAX响应 - 因此,像IE这样的浏览器不支持DOMParser,我使用带有数据URI的同步AJAX调用来解析XML。:)
10赞 HMR 5/10/2013
如果您因为尝试加载 HTML 而不是像 <br> 标签那样的 XML 而遇到错误,请查看此处:developer.mozilla.org/en-US/docs/DOM/DOMParser“适用于其他浏览器的 DOMParser HTML 扩展”下以支持加载 HTML
15赞 John Strood 7/14/2016
@maerics 为什么不能直接说 HTML 解析?text/html
11赞 akauppi 8/5/2016
@Djack 你可以,但随后你会得到自动生成的“html”和“body”标签。
34赞 akauppi 8/5/2016
注意:如果将创建的节点放回浏览器的 DOM(Safari 9.1.2),我发现使用“text/html”而不是“text/xml”至关重要。否则,CSS 渲染无法正常工作。如果使用此选项,请使用“.body”绕过自动插入的 body 元素。
262赞 bobince 6/24/2010 #4

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

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

如果你得到的外部 HTML 元素像这里这样简单,这很容易。如果它可能是其他不能去任何地方的东西,你可能会遇到更多问题。例如,如果它是 ,则必须使父包装器是 .<div><li><ul>

但是IE不能写这样的元素,所以如果你有一个,你必须把整个HTML字符串包装在...中,把它写到并从几个级别中解救出你想要的实际。innerHTML<tr><td><table><tbody><tr></tr></tbody></table>innerHTML<td>

评论

17赞 maerics 2/18/2012
+1 此解决方案可能更便携。
5赞 bryc 2/4/2015
请记住,此方法将丢失事先分配给它的任何事件处理程序或其他属性。
18赞 Muhammad Umer 8/16/2015
@bryc字符串如何附加事件处理程序/
0赞 Danger 12/28/2015
@Muhammad - 也许通过使用类似的东西,尽管这不适用于未在 HTML 中定义的事件处理程序,这也许是您的意思。onclick="..."
0赞 Ari 5/14/2016
如果字符串是这样的呢?some string at the start <div><a href="#">anchor text</a><span>inner text</span></div>string end
6赞 Tower 6/24/2010 #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);

评论

11赞 7/7/2012
您无需在文档中添加“e”。您也不需要对它执行 setAttribute。
1赞 william malo 5/3/2013 #6

你可以这样做:

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);
85赞 Ram Y 10/8/2013 #7

为什么不使用 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

评论

4赞 vsync 9/29/2014
您知道在DOM中会有这个元素才能正常工作吗?无论如何,您都不希望在 DOM 中使用此元素,您只想将字符串转换为内存中的 HTML
1赞 Ron Burk 9/10/2022
好吧,@vsync,这当然是 MDN 文档所说的,但这听起来很可疑,因为这个函数没有理由关心目标节点是否在 DOM 中。使用今天的浏览器 (Chrome),我只是测试了它,不,根本不需要在 DOM 中。任何具有父节点的节点都会使 insertAdjacentHTML() 像蛤蜊一样快乐。想知道是否有任何其他浏览器的行为不同......
2赞 Filling The Stack is What I DO 12/28/2013 #8

下面是一个有用的小代码。

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

评论

2赞 aendra 7/5/2017
呃......这基本上只是@orip的答案,但除了扩展原生和原型之外,还添加了许多完全不必要的内容(您通常不应该这样做)。这是无关紧要的,近乎危险......StringHTMLElement
0赞 Filling The Stack is What I DO 5/6/2018
@aendrew这是针对不同的示例。原型助手恰好是我在整个解决方案中得到的最好的助手之一,我传入了一组 DOM 元素 [ele,ele,ele,ele,ele],所以我不敢苟同。而且,第一次转换为 DOM 元素也很棒。了解有关 DocumentFragment 的更多信息,“没有人使用过”,你就会看到发生了什么。这些是 util 文件中的帮助程序。这就是当今世界开发人员的问题所在,如果不是第三方,他们就一无所知。我从头开始编写我所有的 JS。
0赞 Filling The Stack is What I DO 5/6/2018
为了扩展我上一条评论,在我的大多数 JS 应用程序中,性能都是认真对待的。
2赞 aendra 5/11/2018
我只是说不要污染内置的原型。如今,这被认为是最佳实践,与从头开始编写 JS、使用库或性能完全无关——这是为了防止未来的错误。
0赞 Tamil Vendhan Kanagarasu 1/27/2022
@FillingTheStackisWhatIDO,返回和返回有什么区别,除了后者返回一个节点数组的事实。wrapper.firstChildtoDomElementdf.addChilds(wrapper.children)
0赞 too lazy to log in 6/22/2023 #9

总结:

  1. 制作不可见的元素
  2. 将 HTML 添加到
  3. 通过获取元素的第一个子元素来获取元素

function txtToElem(txt){
let a = document.createElement('div')
a.style.display='none'
document.body.appendChild(a)
a.innerHTML=txt
let b = a.children
document.body.removeChild(a)
return b
}

let htmltext='<span>hello sir</span>'
console.log(txtToElem(htmltext))
//testing that it works as an elem:
document.body.appendChild(txtToElem(htmltext)[0])
<h1>the rest of the website...</h1>

首先,将 div 附加到文档上,通过使用 css 端口将其隐藏起来。hide

然后,使用 div 将文本附加到不可见的 div 中appendChild()

最后,使用 proporty 获取不可见 div 中的元素Element.children

注意:

替换为 也获取嵌套元素a.childrena.childnodes

缺点:

  1. 仅适用于前端应用程序