我想解析一个包含HTML文本的字符串。我想用JavaScript写。

我尝试了纯JavaScript HTML解析器库,但它似乎解析我当前页面的HTML,而不是从字符串。因为当我尝试下面的代码时,它改变了我页面的标题:

var parser = new HTMLtoDOM("<html><head><title>titleTest</title></head><body><a href='test0'>test01</a><a href='test1'>test02</a><a href='test2'>test03</a></body></html>", document);

我的目标是从一个HTML外部页面中提取链接,我读起来就像一个字符串。

你知道一个API来做它吗?


当前回答

在Chrome和Firefox中解析HTML的最快方法是Range#createContextualFragment:

var range = document.createRange();
range.selectNode(document.body); // required in Safari
var fragment = range.createContextualFragment('<h1>html...</h1>');
var firstNode = fragment.firstChild;

我建议创建一个helper函数,如果可用,使用createContextualFragment,否则返回innerHTML。

基准:http://jsperf.com/domparser-vs-createelement-innerhtml/3

其他回答

let content = "<center><h1>404 Not Found</h1></center>"
let result = $("<div/>").html(content).text()

content: <center><h1>404 Not Found</h1></center>, 结果:404 Not Found

function parseElement(raw){
    let el = document.createElement('div');
    el.innerHTML = raw;
    let res = el.querySelector('*');
    res.remove();
    return res;
}

注意:原始字符串不应该多于1个元素

编辑:下面的解决方案只针对HTML“片段”,因为HTML,头部和身体被删除。我想这个问题的解决方案是DOMParser的parseFromString()方法:

const parser = new DOMParser();
const document = parser.parseFromString(html, "text/html");

对于HTML片段,这里列出的解决方案适用于大多数HTML,但在某些情况下它将不起作用。

例如,尝试解析<td>Test</td>。这个不会在div.innerHTML解决方案或DOMParser.prototype.parseFromString或range上工作。createContextualFragment解决方案。td标签丢失,只留下文本。

只有jQuery能很好地处理这种情况。

所以未来的解决方案(MS Edge 13+)是使用模板标签:

function parseHTML(html) {
    var t = document.createElement('template');
    t.innerHTML = html;
    return t.content;
}

var documentFragment = parseHTML('<td>Test</td>');

对于较旧的浏览器,我已经将jQuery的parseHTML()方法提取为一个独立的gist - https://gist.github.com/Munawwar/6e6362dbdf77c7865a99

1的方式

使用document.cloneNode ()

性能:

对document.cloneNode()的调用耗时约0.2249999999977299012毫秒。

也许还会更多。

Var t0, t1, html; T0 = performance.now(); html = document.cloneNode(true); T1 = performance.now(); console.log("调用doSomething耗时" + (t1 - t0) + "毫秒。") html.documentElement.innerHTML = '<!负责人html DOCTYPE html > < > < > <标题>测试< /名称> < /头> <身体> test1 < div id = " test1 " > < / div > < /身体> < / html > '; console.log (html.getElementById (test1));

2方法

使用document.implementation.createHTMLDocument ()

性能:

对document.implementation.createHTMLDocument()的调用耗时约0.14000000010128133毫秒。

Var t0, t1, html; T0 = performance.now(); html = document.implementation.createHTMLDocument("test"); T1 = performance.now(); console.log("调用doSomething耗时" + (t1 - t0) + "毫秒。") html.documentElement.innerHTML = '<!负责人html DOCTYPE html > < > < > <标题>测试< /名称> < /头> <身体> test1 < div id = " test1 " > < / div > < /身体> < / html > '; console.log (html.getElementById (test1));

3路

使用document.implementation.createDocument ()

性能:

对document.implementation.createHTMLDocument()的调用耗时约0.14000000010128133毫秒。

var t0 = performance.now();
  html = document.implementation.createDocument('', 'html', 
             document.implementation.createDocumentType('html', '', '')
         );
var t1 = performance.now();

console.log("Call to doSomething took " + (t1 - t0) + " milliseconds.")

html.documentElement.innerHTML = '<html><head><title>Test</title></head><body><div id="test1">test</div></body></html>';

console.log(html.getElementById("test1"));

4路

使用新文档()

性能:

调用document.implementation.createHTMLDocument()耗时约0.13499999840860255毫秒。

请注意

ParentNode。2020年附加实验技术。

var t0, t1, html;

t0 = performance.now();
//---------------
html = new Document();

html.append(
  html.implementation.createDocumentType('html', '', '')
);
    
html.append(
  html.createElement('html')
);
//---------------
t1 = performance.now();

console.log("Call to doSomething took " + (t1 - t0) + " milliseconds.")

html.documentElement.innerHTML = '<html><head><title>Test</title></head><body><div id="test1">test1</div></body></html>';

console.log(html.getElementById("test1"));

我认为最好的方法是这样使用这个API:

//Table string in HTML format const htmlString = '<table><tbody><tr><td>Cell 1</td><td>Cell 2</td></tr></tbody></table>'; //Parse using DOMParser native way const parser = new DOMParser(); const $newTable = parser.parseFromString(htmlString, 'text/html'); //Here you can select parts of your parsed html and work with it const $row = $newTable.querySelector('table > tbody > tr'); //Here i'm printing the number of columns (2) const $containerHtml = document.getElementById('containerHtml'); $containerHtml.innerHTML = ['Your parsed table have ', $row.cells.length, 'columns.'].join(' '); <div id="containerHtml"></div>