【问题标题】:JQuery .find() failing on an .ajax() resultJQuery .find() 在 .ajax() 结果上失败
【发布时间】:2015-08-25 03:35:10
【问题描述】:

我正在开发一个 Chrome 扩展程序,它在特定条件下执行 $.ajax() 请求,然后使用返回的 HTML 中特定元素的信息。现在,我只是想让它访问特定元素并将其记录到控制台以确保它正常工作。

首先,我相当确定HTML 已成功检索。当我直接记录结果时,输出与我在 Chrome 中查看页面源时的结果相同。我也尝试过使用$.parseHTML(),它在登录时会为我提供一系列顶级子项。使用选择器会返回与选择器匹配的直接子元素的数组,但它们不适用于这些子元素的子元素(等等)。

我已经看过几个帖子,并尝试了各种方法,例如使用$(<selector>,<context>)$(<result>).filter(<selector>)$(<result>).find(<selector>),但均无济于事。每次我尝试记录这些时,我都会得到一个长度为 0 的对象。

$.ajax({jsonp: false, dataType: "html",url: getUWFlowLink($(this).attr('href')), success: function(siteHTML){

    console.log($("p.description",siteHTML));
    console.log($("p.description",$.parseHTML(siteHTML)));
    console.log($(siteHTML).find("p.description"));
    console.log($($.parseHTML(siteHTML)).find("p.description"));
    console.log($(siteHTML).filter("p.description"));
    console.log($($.parseHTML(siteHTML)).filter("p.description"));

}});

所有这些日志都只返回具有0 长度的对象。尝试记录.html() 会导致输出undefined,尝试记录.text() 会导致输出为空字符串。一个示例页面,供参考是here。我试图访问的元素是顶部的描述信息(“应用程序的化学原理......”),它在 HTML 中的位置(深几级)可以通过检查元素找到。

【问题讨论】:

  • 你可能有跨域问题?
  • 我不太确定——这是我第一次使用 JQuery,更不用说 chrome dev 和 ajax。但据我所知,当站点被放入清单的权限并且您指定jsonp:"false" 时,可以使用chrome 扩展跨域。尽管我不是 100% 的,但 HTML 似乎已成功检索。
  • 如果您从不同的域加载 HTML 文件而不是 ajax 调用,并且您没有在服务器上进行特殊设置,您将遇到跨域问题。数据会发送到浏览器,但浏览器不会让 javascript 拥有它。

标签: jquery html ajax google-chrome-extension jquery-selectors


【解决方案1】:

试试这样的

var $result = $('<div />').append(siteHTML);
$result.find('p.description');

jQuery 需要一个树结构来遍历和执行它的操作。在没有根元素的情况下直接尝试使用.find() 是行不通的。在上述情况下,$('&lt;div/&gt;') 将是根元素,通过附加结果,jquery 将在上面遍历它并找到p.description

【讨论】:

  • 谢谢。这似乎解决了我与find() 的问题。
【解决方案2】:

如果您对链接的示例页面执行“查看页面源代码”,您会发现您要查找的元素如下所示:

<script type="text/html" id="course-inner-tpl">

<div class="row-fluid">
  <div class="span6 left-col">
    <p class="description"><%- course.get('description') %></p>
...

这意味着元素在加载后会在浏览器上动态呈现。当 jQuery 解析它时,它不会成为 DOM 树的一部分,因为它位于 &lt;script&gt; 标记内。

请注意,您还可以在同一页面上的静态&lt;meta&gt; 标记中找到课程描述,您应该可以访问该标记。

编辑:如果您需要更多信息,您可以解析相关脚本来获取它。以下代码将遍历页面中的所有脚本,找到包含信息的脚本,提取定义 coursOjb 对象的文本,并将其解析为 JSON:

$('<div />').append(siteHTML).find('script').each(function(s) {
   var t = $(this).text();
   var p = t.indexOf('window.pageData.courseObj = {');
   if( p > 0 ) {
       var e = t.indexOf(';', p);
       var d = JSON.parse(t.substring(p+28, e));
       console.log(d.code);
       console.log(d.name);
       console.log(d.description);
       console.log(d.prereqs);
   }
});

【讨论】:

  • 感谢您指出这一点。当我使用 &lt;meta&gt; 标签中的版本时,它现在可以工作了。有没有办法让我获得动态渲染的数据?我需要的页面上的其他一些元素似乎在其他地方没有静态元素。
  • 没有简单的方法。一种方法是尝试在 iframe 中加载页面并等待它呈现元素。另一种方法是尝试解析或评估包含数据的&lt;script&gt; 元素(以window.pageData.courseObj = ... 开头的元素。
  • 由于我对HTML 的了解有限,为了提高效率/开销,我倾向于尝试第二种方法...我将如何使用该部分获取信息?对我来说,它看起来像 JSON,但老实说,我不知道如何使用 JQuery
  • 我认为在我对所有这些新概念的困惑中,我完全忘记了字符串操作等简单策略!这非常有效 - 你是我的英雄。
【解决方案3】:

如果您成功获取 HTML 并且没有遇到 Access-Control-Allow-Origin 问题,我已经在测试用例中测试了以下内容:

var description = $(siteHTML).find("p.description").html();
console.log(description);

如果您可以使用 console.log(siteHTML) 并且它会为您提供输出,那么您应该能够使用 jQuery 查询响应,但是当不将 HTML 添加到 DOM 时,查询选择器的工作可能会有一些限制.

【讨论】:

    猜你喜欢
    • 2012-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-25
    • 1970-01-01
    • 2011-09-21
    • 1970-01-01
    相关资源
    最近更新 更多