将 HTML 字符串解析为 DOM 的 Javascript 函数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6130237/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Javascript function to parse HTML string into DOM?
提问by cronoklee
Is there a good JS function or class that can seamlessly parse a string of HTML into the DOM without resetting existing content? I'm trying to find an easy way to duplicate a complicated table row at the top of the table.
有没有好的JS函数或者类可以无缝地将一串HTML解析成DOM而不用重置现有内容?我试图找到一种简单的方法来复制表格顶部的复杂表格行。
It obviously will work like this:
它显然会像这样工作:
element.innerHTML = newHTML + element.innerHTML;
However, this causes the browser to reload the entire table which resets the scroll position and deletes any unsaved editable content in the table.
但是,这会导致浏览器重新加载整个表格,从而重置滚动位置并删除表格中任何未保存的可编辑内容。
UPDATE:
更新:
I'm not using jQuery for this project. Here's an idea I found somewhere but I cant get it working:
我没有在这个项目中使用 jQuery。这是我在某处找到的一个想法,但我无法让它发挥作用:
var templateRow = document.getElementById( 'templateRow' );
var newhtml = "<tr id='row"+lastID+"'>"+'templateRow'.innerHTML+"</tr>";
var range = document.createRange();
range.selectNode( 'templateRow' );
var parsedHTML = range.createContextualFragment( newhtml );
templateRow.appendChild( parsedHTML )
回答by bobince
Are you attempting to insert content into an existing element, without disturbing the content that's already in there?
您是否试图将内容插入到现有元素中,而不会干扰已经存在的内容?
The most straightforward answer is insertAdjacentHTML
. This is an IE scripting extension, since standardised by HTML5:
最直接的答案是insertAdjacentHTML
。这是一个 IE 脚本扩展,因为由 HTML5 标准化:
mydiv.insertAdjacentHTML('afterBegin', '<p>Some new stuff</p><p>to prepend</p>');
Unfortunately it is not implemented everywhere. So elsewhere you have to create a new element, set innerHTML
on it and then transfer the contents to the target:
不幸的是,它并未在所有地方实施。因此,您必须在其他地方创建一个新元素,对其进行设置innerHTML
,然后将内容传输到目标:
var container= document.createElement('div');
container.innerHTML= '<p>Some new stuff</p><p>to prepend</p>';
while (container.lastChild)
mydiv.insertBefore(container.lastChild, mydiv.firstChild);
If you have a lot of new content, this will be slow. You can speed it up on browsers that support DOM Range by making a Range over the new content, extracting it to a DocumentFragment and inserting that fragment into the target node in one go.
如果你有很多新内容,这会很慢。您可以在支持 DOM Range 的浏览器上加快速度,方法是在新内容上创建 Range,将其提取到 DocumentFragment 并将该片段一次性插入目标节点。
Unfortunately (again), whether you are using insertAdjacentHTML
or innerHTML
, there are elements that IE<9 won't set HTML on: most notably <table>
and its relations. So in that case you have to surround the HTML in a suitable wrapper for the element name:
不幸的是(再次),无论您使用insertAdjacentHTML
或innerHTML
,IE<9 都不会在<table>
其上设置 HTML 的元素:最值得注意的是及其关系。因此,在这种情况下,您必须将 HTML 包含在元素名称的合适包装器中:
container.innerHTML= '<table><tbody>'+newRowsHTML+'</tbody></table>';
and then extract the contents from the inner element to put in the target.
然后从内部元素中提取内容放入目标。
The good thing about this is that with tables if you have a lot of new rows you can put them in a single <tbody>
and insertBefore
/appendChild
that body to put all the rows in in one go, which is quicker than one-by-one.
这样做的好处是,对于表格,如果您有很多新行,您可以将它们放在一个单独的<tbody>
和insertBefore
/appendChild
该主体中以一次性放入所有行,这比逐行要快。
回答by Brad Christie
DISCLAIMER:I don't write code these days out of jQuery. SImply because I hate chasing down the browser quirks between using property A on this browser, and property B on this one. That said, this works in Firefox, but is more about getting the concept down. I just wanted to be as up-front as possible.
免责声明:这些天我不使用 jQuery 编写代码。仅仅是因为我讨厌在这个浏览器上使用属性 A 和在这个浏览器上使用属性 B 之间追逐浏览器的怪癖。也就是说,这在 Firefox 中有效,但更多的是关于降低概念。我只是想尽可能提前。
DEMO
演示
Basically, you do the following:
基本上,您执行以下操作:
- Have your
<table>
that contains all the "original" / "untainted" data you don't want fussed with. [table1] - Have a string with additional data you need inserted in to this original table, without manipulating (or otherwise impeding) on whatever is already going on with table1. [sampleData]
- Create a new
<table>
[table2]and add it to the document (but style it so it's completely invisible). Depending on the content of the string, you may use a<div>
, but whichever method you go it should be invisible (after all, all we're using it for is the ability to parse the html string usinginnerHTML
). - Now take the contents of that new
<table>
[table2](or<div>
) and use javascript and DOM to push those items tot he new table.
- 让你的
<table>
那些包含你不想大惊小怪的所有“原始”/“未受污染”的数据。[表格1] - 将一个包含额外数据的字符串插入到这个原始表中,而不需要操纵(或以其他方式阻碍)table1 中已经发生的任何事情。[样本数据]
- 创建一个新的
<table>
[table2]并将其添加到文档中(但设置样式使其完全不可见)。根据字符串的内容,您可以使用<div>
,但无论您采用哪种方法,它都应该是不可见的(毕竟,我们使用它的目的只是能够使用 解析 html 字符串innerHTML
)。 - 现在获取新
<table>
[table2](或<div>
)的内容并使用 javascript 和 DOM 将这些项目推送到新表。
This will avoid using innerHTML
again on the new table, forcing a reload and losing anything that's going on already.
这将避免innerHTML
在新表上再次使用,强制重新加载并丢失已经发生的任何事情。
回答by cem
function parseHTML(html) {
var el = document.createElement("div");
el.innerHTML = html;
return el.childNodes;
}
var nodes = parseHTML("<span>Text</span>");
回答by Tadeck
Use for example jQuery (documentation of the specific method - with examples - is here):
使用例如 jQuery(特定方法的文档 - 带有示例 - 在这里):
var your_html_code = '<table>...</table>';
then use it like that:
然后像这样使用它:
jQuery(your_html_code);
See more within similar question page.
在类似问题页面中查看更多信息。
回答by Nick
I think I understand what you are trying to do. If you need a .NET library that will let you easly parse HTMl try Html Agility Pack
我想我明白你想要做什么。如果您需要一个可以让您轻松解析 HTMl 的 .NET 库,请尝试Html Agility Pack
You could parse html just like you parse xml using the XMLDocument api in .NET. This is a .NET dll so you would have to do this on the server side of coarse. If you need the DOM to be manipulated without post back you could always create a service on the web server and make an ajax call that includes the html.
您可以像使用 .NET 中的 XMLDocument api 解析 xml 一样解析 html。这是一个.NET dll,因此您必须在粗略的服务器端执行此操作。如果您需要在不回发的情况下操作 DOM,您始终可以在 Web 服务器上创建一个服务并进行包含 html 的 ajax 调用。
Does that make sense?
那有意义吗?
回答by hugomg
innerHTML
is the way to go. Perhaps you could try reseting the inner HTML of only the <td>
s you are changing and see if that gives the effect you want?
innerHTML
是要走的路。也许您可以尝试仅重置<td>
您正在更改的s的内部 HTML,看看是否会产生您想要的效果?
You could also have a look at the table manipulation methodsin the DOM.
您还可以查看DOM中的表操作方法。
回答by cronoklee
Sincere thanks for all the replies - some of which are quite detailed. I've managed to solve the problem using a combination of table.insertRow() and innerHTML. It seems to be the quickest and most clean solution to the problem. Hope it and the other replies on this page help someone else out!
真诚地感谢所有的回复——其中一些非常详细。我已经设法使用 table.insertRow() 和 innerHTML 的组合来解决这个问题。这似乎是解决问题的最快和最干净的解决方案。希望它和此页面上的其他回复可以帮助其他人!
Rather than updating the entire table html, we add a new row to the DOM and insert the html into that:
我们不是更新整个表格 html,而是向 DOM 添加一个新行并将 html 插入其中:
function $(id){ //just a shortcut function
return document.getElementById(id);
}
var lastID = 10; //id number of last table row
function addRow(){
var newhtml = $('templateRow').innerHTML); //copy the template row
var t = $('aTable').insertRow(2) //insert a row in the desired position
t.id = 'row'+lastID; //update the new tr's id
t.innerHTML = newhtml //replace the innerHTML of the new row
lastID++; //increment the counter for next time
}