我想解析一个包含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来做它吗?
这很简单:
const parser = new DOMParser();
const htmlDoc = parser.parseFromString(txt, 'text/html');
// do whatever you want with htmlDoc.getElementsByTagName('a');
根据MDN,要在chrome中做到这一点,你需要像这样解析XML:
const parser = new DOMParser();
const htmlDoc = parser.parseFromString(txt, 'text/xml');
// do whatever you want with htmlDoc.getElementsByTagName('a');
webkit目前不支持它,你必须遵循Florian的回答,而且它在大多数情况下在移动浏览器上是否有效还不得而知。
编辑:现在广泛支持
创建一个虚拟DOM元素并将字符串添加到其中。然后,您可以像操作任何DOM元素一样操作它。
var el = document.createElement( 'html' );
el.innerHTML = "<html><head><title>titleTest</title></head><body><a href='test0'>test01</a><a href='test1'>test02</a><a href='test2'>test03</a></body></html>";
el.getElementsByTagName( 'a' ); // Live NodeList of your anchor elements
编辑:添加一个jQuery的答案,以取悦粉丝!
var el = $( '<div></div>' );
el.html("<html><head><title>titleTest</title></head><body><a href='test0'>test01</a><a href='test1'>test02</a><a href='test2'>test03</a></body></html>");
$('a', el) // All the anchor elements
要在node.js中做到这一点,可以使用node-html-parser这样的HTML解析器。语法如下所示:
import { parse } from 'node-html-parser';
const root = parse('<ul id="list"><li>Hello World</li></ul>');
console.log(root.firstChild.structure);
// ul#list
// li
// #text
console.log(root.querySelector('#list'));
// { tagName: 'ul',
// rawAttrs: 'id="list"',
// childNodes:
// [ { tagName: 'li',
// rawAttrs: '',
// childNodes: [Object],
// classNames: [] } ],
// id: 'list',
// classNames: [] }
console.log(root.toString());
// <ul id="list"><li>Hello World</li></ul>
root.set_content('<li>Hello World</li>');
root.toString(); // <li>Hello World</li>
在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
我不得不使用Angular NGX Bootstrap弹出窗口中解析的元素的innerHTML。这是对我有效的解决办法。
public htmlContainer = document。createElement('html');
在构造函数
this.htmlContainer.innerHTML = '';setTimeout(() => { this.convertToArray(); });
convertToArray() {
const shapesHC = document.getElementsByClassName('weekPopUpDummy');
const shapesArrHCSpread = [...(shapesHC as any)];
this.htmlContainer = shapesArrHCSpread[0];
this.htmlContainer.innerHTML = shapesArrHCSpread[0].textContent;
}
在html中
<div class="weekPopUpDummy" [popover]="htmlContainer.innerHTML" [adaptivePosition]="false" placement="top" [outsideClick]="true" #popOverHide="bs-popover" [delay]="150" (onHidden)="onHidden(weekEvent)" (onShown)="onShown()">
编辑:下面的解决方案只针对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