将整个HTML文档从字符串解析为jQuery

wjd*_*jdp 6 jquery

我有一个通过$.get电话获取的文档,它是一个很大的HTML文档。我需要使用jQuery从中获取元素。

我正在尝试这个(在咖啡脚本中):

$.get url, (data) ->
  title = $(data).find('title').text()
Run Code Online (Sandbox Code Playgroud)

这行不通。在浏览器控制台,我削成下来到$(document.documentElement.outerHTML).find('title')这里document.documentElement.outerHTML给文档的字符串。

我尝试了jQuery.parseHTML,结果相同。

Kyl*_*Mit 9

TL;DR ... 使用DOMParserAPI

var htmlString = "<html><head><title>Name</title></head><body><div class='content'>Hello</div></body></html>";
var htmlDoc = (new DOMParser()).parseFromString(htmlString, "text/xml");
Run Code Online (Sandbox Code Playgroud)

不幸的是,目前的答案并没有遇到很多边缘情况

你应该使用$.parseHTML(htmlString),因为它立即是有损耗的。如果我们检查 上的源代码$.parseHtml,它会调用buildFragment它创建一个临时 DOM 元素并设置innerHTML属性。

内部HTML解析

元素innerHTML提供 API 用于:

这是Html 片段解析算法规范

以一个示例字符串为例,这是尝试各种 HTML 解析方法的结果:

var htmlString = "<html><head><title>Name</title></head><body><div class='content'>Hello</div></body></html>";

function ParseHtmlTests() {

  /*** $.parseHTML ***/
  var $parseHtml = $.parseHTML(htmlString)

  console.LogOutput(
    '1. $.parseHTML',
    $parseHtml,
    $parseHtml.map(function(el, i) { return el.outerHTML }),
    $($parseHtml).find("title").text(),
    $($parseHtml).find(".content").text()
  )


  /*** tempDiv.innerHTML ***/
  var tempDiv = document.createElement("div")
  tempDiv.innerHTML = htmlString

  console.LogOutput(
    '2. tempDiv.innerHTML',
    tempDiv,
    tempDiv.outerHTML,
    $(tempDiv).find("title").text(),
    $(tempDiv).find(".content").text()
  )


  /*** divAppendContents ***/
  var $divAppendContents = $('<div></div>').append(htmlString)

  console.LogOutput(
    '3. divAppendContents',
    $divAppendContents,
    $divAppendContents.html(),
    $divAppendContents.find("title").text(),
    $divAppendContents.find(".content").text()
  )


  /*** tempHtml.innerHTML ***/
  var tmpHtml = document.createElement( 'html' );
  tmpHtml.innerHTML = htmlString;

  console.LogOutput(
   '4. tempHtml.innerHTML',
    tmpHtml,
    tmpHtml.outerHTML,
    tmpHtml.getElementsByTagName('title')[0].innerText,
    tmpHtml.getElementsByClassName('content')[0].innerText
  )


  /*** DOMParser.parseFromString ***/
  var htmlDoc = (new DOMParser()).parseFromString(htmlString, "text/xml");

  console.LogOutput(
    '5. DOMParser.parseFromString',
    htmlDoc,
    htmlDoc.documentElement.outerHTML,
    htmlDoc.documentElement.getElementsByTagName('title')[0].innerHTML,
    htmlDoc.documentElement.getElementsByClassName('content')[0].innerHTML
  )
}

/*** Create Console Log Methods ***/
console.group = console.group || function(msg) {
  console.log(msg)
}
console.groupEnd = console.groupEnd || function(msg) {
  console.log("----------------------------")
}
console.LogOutput = function(method, dom, html, title, content) {
  console.group(method);
  console.log("DOM:", dom)
  console.log("HTML:", html)
  console.log("Title:", title)
  console.log("Content:", content)
  console.groupEnd();
};

/*** Execute Script ***/
ParseHtmlTests()
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
Run Code Online (Sandbox Code Playgroud)

这是上述 chrome 脚本的输出:

输出

最好的方法似乎是通过设置innerHTML临时 HTML 文档或使用DOMParserAPI来创建 HTML Root 对象

进一步阅读:


Mig*_*nez 7

之所以不起作用,是因为jQuery希望DOM节点找到'title'标签。如您所述,您需要先解析html文本。

这里这里,解决方案是解析字符串并将其附加到时间div(或其他元素)中:

var tempDom = $('<div></div>').append($.parseHTML(str));
Run Code Online (Sandbox Code Playgroud)

然后,您可以进行操作tempDom以查找元素。

工作演示http : //codepen.io/anon/pen/wKwLMP