Разбор строки HTML с помощью JS
Я искал решение, но ничего не значимо, поэтому вот моя проблема:
Я хочу проанализировать строку, содержащую текст 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);
Моя цель - извлечь ссылки с внешней страницы HTML, которую я читаю, как строку.
Вы знаете API для этого?
Ответы
Ответ 1
Создайте фиктивный элемент 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
Ответ 2
Это довольно просто:
var parser = new DOMParser();
var htmlDoc = parser.parseFromString(txt, 'text/html');
// do whatever you want with htmlDoc.getElementsByTagName('a');
Согласно MDN, чтобы сделать это в Chrome, вам нужно проанализировать как XML так:
var parser = new DOMParser();
var htmlDoc = parser.parseFromString(txt, 'text/xml');
// do whatever you want with htmlDoc.getElementsByTagName('a');
В настоящее время он не поддерживается webkit, и вам придется следовать ответу Florian, и в большинстве случаев он неизвестен для мобильных браузеров.
Изменение: теперь широко поддерживается
Ответ 3
EDIT: нижеприведенное решение предназначено только для 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>');
Для старых браузеров я извлек метод jQuery parseHTML() в независимый gist - https://gist.github.com/Munawwar/6e6362dbdf77c7865a99
Ответ 4
var $doc = new DOMParser().parseFromString($html, "text/html");
$As = $('a', $doc);
Ответ 5
Следующая функция parseHTML
возвратит либо:
Код:
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;
}
}
Как пользоваться:
var links = parseHTML('<!doctype html><html><head></head><body><a>Link 1</a><a>Link 2</a></body></html>').getElementsByTagName('a');
Ответ 6
Самый быстрый способ анализа HTML в Chrome и Firefox - это Range # createContextualFragment:
var range = document.createRange();
range.selectNode(document.body); // required in Safari
var fragment = range.createContextualFragment('<h1>html...</h1>');
var firstNode = fragment.firstChild;
Я бы рекомендовал создать вспомогательную функцию, которая использует createContextualFragment, если она доступна, и возвращается в innerHTML в противном случае.
Контрольный показатель: http://jsperf.com/domparser-vs-createelement-innerhtml/3
Ответ 7
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>') );
Только допустимый дочерний Node
в родительском Node
(начало Range
) будет проанализирован. В противном случае могут возникнуть неожиданные результаты: // <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>');
Ответ 8
Если вы открыты для использования jQuery, у него есть хорошие возможности для создания отдельных элементов DOM из строк HTML. Затем их можно запросить с помощью обычных средств, например:
var 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>";
var anchors = $('<div/>').append(html).find('a').get();
Изменить - просто увидел @Florian ответ, который является правильным. Это в основном то, что он сказал, но с jQuery.
Ответ 9
(adsbygoogle = window.adsbygoogle || []). push ({google_ad_client: "ca-pub-3323261257580508", enable_page_level_ads: true});