sta*_*age 227 html javascript dom html-parsing
我搜索了一个解决方案,但没有任何相关性,所以这是我的问题:
我想解析一个包含HTML文本的字符串.我想用JavaScript做.
我试过这个库,但它似乎解析了我当前页面的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);
Run Code Online (Sandbox Code Playgroud)
我的目标是从HTML外部页面中提取链接,就像字符串一样.
你知道一个API来做吗?
Flo*_*ine 347
创建一个虚拟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
Run Code Online (Sandbox Code Playgroud)
编辑:添加一个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
Run Code Online (Sandbox Code Playgroud)
Cil*_*lan 201
这很简单:
var parser = new DOMParser();
var htmlDoc = parser.parseFromString(txt, 'text/html');
// do whatever you want with htmlDoc.getElementsByTagName('a');
Run Code Online (Sandbox Code Playgroud)
根据MDN,要在chrome中执行此操作,您需要解析为XML,如下所示:
var parser = new DOMParser();
var htmlDoc = parser.parseFromString(txt, 'text/xml');
// do whatever you want with htmlDoc.getElementsByTagName('a');
Run Code Online (Sandbox Code Playgroud)
它目前不受webkit的支持,您必须遵循Florian的答案,并且在大多数情况下在移动浏览器上工作是未知的.
编辑:现在广泛支持
Mun*_*war 16
编辑:下面的解决方案仅适用于HTML"片段",因为删除了html,head和body.我想这个问题的解决方案是DOMParser的parseFromString()方法.
对于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.cloneNode(true);
}
var documentFragment = parseHTML('<td>Test</td>');
Run Code Online (Sandbox Code Playgroud)
对于旧版浏览器,我已经将jQuery的parseHTML()方法提取到一个独立的要点 - https://gist.github.com/Munawwar/6e6362dbdf77c7865a99
var $doc = new DOMParser().parseFromString($html, "text/html");
$As = $('a', $doc);
Run Code Online (Sandbox Code Playgroud)
以下函数parseHTML将返回:
a Document当您的文件以doctype开头时.
a DocumentFragment当您的文件不以doctype开头时.
function parseHTML(markup) {
if (markup.toLowerCase().trim().indexOf('<!doctype') === 0) {
var doc = document.implementation.createHTMLDocument("");
doc.documentElement.innerHTML = markup;
return doc;
} else if ('content' in document.createElement('template')) {
// Template tag exists!
var el = document.createElement('template');
el.innerHTML = markup;
return el.content;
} else {
// Template tag doesn't exist!
var docfrag = document.createDocumentFragment();
var el = document.createElement('body');
el.innerHTML = markup;
for (i = 0; 0 < el.childNodes.length;) {
docfrag.appendChild(el.childNodes[i]);
}
return docfrag;
}
}
Run Code Online (Sandbox Code Playgroud)
var links = parseHTML('<!doctype html><html><head></head><body><a>Link 1</a><a>Link 2</a></body></html>').getElementsByTagName('a');
Run Code Online (Sandbox Code Playgroud)
小智 6
我认为最好的方法是像这样使用这个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(' ');Run Code Online (Sandbox Code Playgroud)
<div id="containerHtml"></div>Run Code Online (Sandbox Code Playgroud)
在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;
Run Code Online (Sandbox Code Playgroud)
我建议创建一个辅助函数,如果可用则使用createContextualFragment,否则返回innerHTML.
基准:http://jsperf.com/domparser-vs-createelement-innerhtml/3
const parse = Range.prototype.createContextualFragment.bind(document.createRange());
document.body.appendChild( parse('<p><strong>Today is:</strong></p>') ),
document.body.appendChild( parse(`<p style="background: #eee">${new Date()}</p>`) );
Run Code Online (Sandbox Code Playgroud)
Node父级Node( 的开头)中的有效 childRange才会被解析。否则,可能会出现意想不到的结果:
// <body> is "parent" Node, start of Range
const parseRange = document.createRange();
const parse = Range.prototype.createContextualFragment.bind(parseRange);
// Returns Text "1 2" because td, tr, tbody are not valid children of <body>
parse('<td>1</td> <td>2</td>');
parse('<tr><td>1</td> <td>2</td></tr>');
parse('<tbody><tr><td>1</td> <td>2</td></tr></tbody>');
// Returns <table>, which is a valid child of <body>
parse('<table> <td>1</td> <td>2</td> </table>');
parse('<table> <tr> <td>1</td> <td>2</td> </tr> </table>');
parse('<table> <tbody> <td>1</td> <td>2</td> </tbody> </table>');
// <tr> is parent Node, start of Range
parseRange.setStart(document.createElement('tr'), 0);
// Returns [<td>, <td>] element array
parse('<td>1</td> <td>2</td>');
parse('<tr> <td>1</td> <td>2</td> </tr>');
parse('<tbody> <td>1</td> <td>2</td> </tbody>');
parse('<table> <td>1</td> <td>2</td> </table>');
Run Code Online (Sandbox Code Playgroud)
*_*лов 5
1 种方式
使用document.cloneNode()
性能为:
调用document.cloneNode()大约花费了 0.22499999977299012 毫秒。
也许还会更多。
var t0, t1, html;
t0 = performance.now();
html = document.cloneNode(true);
t1 = performance.now();
console.log("Call to doSomething took " + (t1 - t0) + " milliseconds.")
html.documentElement.innerHTML = '<!DOCTYPE html><html><head><title>Test</title></head><body><div id="test1">test1</div></body></html>';
console.log(html.getElementById("test1"));Run Code Online (Sandbox Code Playgroud)
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("Call to doSomething took " + (t1 - t0) + " milliseconds.")
html.documentElement.innerHTML = '<!DOCTYPE html><html><head><title>Test</title></head><body><div id="test1">test1</div></body></html>';
console.log(html.getElementById("test1"));Run Code Online (Sandbox Code Playgroud)
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"));
Run Code Online (Sandbox Code Playgroud)
4路
使用new Document()
性能为:
调用document.implementation.createHTMLDocument()大约花费了 0.13499999840860255 毫秒。
ParentNode.append是2020年的实验技术。
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"));
Run Code Online (Sandbox Code Playgroud)
要在 node.js 中执行此操作,您可以使用 HTML 解析器,例如node-html-parser。语法如下:
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>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
359217 次 |
| 最近记录: |