【问题标题】:Simple jQuery ajax example not finding elements in returned HTML简单的 jQuery ajax 示例未在返回的 HTML 中找到元素
【发布时间】:2010-11-05 05:30:54
【问题描述】:

我正在尝试学习 jQuery 的 ajax 函数。我已经让它工作了,但是 jQuery 在返回的 HTML DOM 中找不到元素。在与 jquery 相同的文件夹中,运行此页面:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
    <title>runthis</title>

    <script type="text/javascript" language="javascript" src="jquery-1.3.2.min.js"></script>

    <script tyle="text/javascript">
    $(document).ready(function(){
        $('input').click(function(){
            $.ajax({
                type : "GET",
                url : 'ajaxtest-load.html',
                dataType : "html",
                success: function(data) {

                alert( data ); // shows whole dom

                alert( $(data).find('#wrapper').html() ); // returns null

                },
                error : function() {
                    alert("Sorry, The requested property could not be found.");
                }
            });
        });
    });
    </script

</head>
<body>
    <input type="button" value="load" />
</body>
</html>

加载此页面“ajaxtest-load.html”:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
    <title>load this</title>

</head>
<body>
    <div id="wrapper">
    test
    </div>
</body>
</html>

它会发出两个警报。一个显示 DOM 已加载,但第二个显示 NULL 而不是#wrapper。我究竟做错了什么?

编辑:我正在加载“ajaxtest-load.html”,其中包括整个标题,再次包括 jquery。是这个问题吗?

【问题讨论】:

  • 也许清理顶部代码并在 'ajaxtest-load.html' 上发布 html 的样子
  • 第二个 html 块是 ajaxtest-load.html。编辑了描述。对此感到抱歉。

标签: jquery ajax dom parsing


【解决方案1】:

这不是一个直接的答案,但可能有助于澄清事情。

回调函数的data参数可以做成一个jQuery(1.6.2)对象$(data),包含HTML响应的不同部分:

  • 实际文档之前的内容,例如文档类型声明或可忽略的空白文本节点。
  • head 元素的内容。
  • body 元素的内容。

html、head 和 body 元素不在数据对象中。由于 head 和 body 中包含的元素数量可能会有所不同,因此不应通过像 $(data)[2] 这样的索引来获取它们。相反,对这个对象应用一个过滤器,如下所示:

        $.get(
          uri,
          function(data, textStatus, jqXHR){
            var $doc = $(data);
            var title = $doc.filter('title').text();
            // title is the title from the head element.
            // Do whatever you need to do here.
          }
        );

过滤正确的元素后,您可以使用 find() 应用更多选择器。

不幸的是,在 IE 中,头部元素不是 $(data) 的一部分。我不知道这是为什么。

【讨论】:

  • +1 因为这也适用于最新的.ajax() 实现。我刚刚将 .find() 更改为 .filter() 并且一切正常!
  • 我花了几个小时试图弄清楚为什么它找不到特定元素,但它找到了里面的所有元素。将.find() 切换为.filter() 使其工作。太感谢了!另外,我想打一个婴儿的脸。不开玩笑,我就是这么生气。
【解决方案2】:

通过使用.load(),我已经成功地从完整的 html 文档中加载了 sn-ps。

要在 DOM 中创建一个带有提取 html 的新块,我这样做:

$('<div></div>').appendTo('body').load('some-other-document.html div#contents');

如果它不适合您,请确保您使用的是最新版本(或 1.2 后)的 jQuery。有关更多示例,请参阅documentation for .load

编辑:

但请注意,上述示例的结果将是:

<div><div id="contents">...</div></div>

要仅获取另一个文档中#contents div 的内容,请在加载函数调用中使用回调函数。

$('<div></div>').load('some-other-document.html div#contents', null, 
    function (responseText, textStatus, XMLHttpRequest) {
        if (textStatus == success) {
            $('<div></div>').appendTo('body').html($(this).html());
        }
    }
);

【讨论】:

  • 我喜欢这个,因为它避免了立即将返回的数据粘贴到文档中。仅供参考,如果您不介意创建一个虚拟 div 并将返回的数据插入其中,您可以在 $.get() 中执行此操作。这基本上就是 .load() 在幕后所做的。
  • 谢谢,这是我项目所需的完美解决方案。在我的 ajax 调用中,我收到用户请求的数据(工具提示、页面内容或其他内容),并且它需要始终伴随一个 json 对象来更新用户的小部件......划分请求的信息和 json对象已通过发送 2 个 div 执行,您的技术允许我执行 .find() 以返回所需的数据。再次感谢
【解决方案3】:

我发现如果 ajaxtest-load.html 没有 或

标签而只有几个 html 元素,它确实 工作。

编辑:

如果输入必须是一个完整的 HTML 页面,也许你可以先用字符串操作去掉你不想要的标签.. 任何人?

编辑 2:

模糊地记得 Javascript/DOM 允许“临时文档”,您可以对其进行操作并使用其中的结果,然后进行一些谷歌搜索产生了一个 parseHTML 函数 (http://www.daniweb.com/forums/post874892-2.html),我已经对其进行了调整以返回正确的位:

$(document).ready(function(){
  $('input').click(function(){
    $.ajax({
      type : "POST",
      url : 'ajaxtest-load.html',
      dataType : "html",
      success: function(data) {
        alert( data ); // shows whole dom
        var gotcha = parseHTML(data, 'wrapper');
        if (gotcha) {
          alert($(gotcha).html());
        }else{
          alert('ID not found.');
        }
      },
      error : function() {
        alert("Sorry, The requested property could not be found.");
      }
    });
  });
});

function parseHTML(html, idStr) {
  var root = document.createElement("div");
  root.innerHTML = html;
  // Get all child nodes of root div
  var allChilds = root.childNodes;
  for (var i = 0; i < allChilds.length; i++) {
    if (allChilds[i].id && allChilds[i].id == idStr) {
      return allChilds[i];
    }
  }
  return false;
}

这行得通吗?

【讨论】:

  • 哦,也许是一个正则表达式来去除身体或其他什么?然后使用 jQuery 将其转换为我可以 .find() 上的对象?
  • 类似的东西,是的。我会提供一个示例,但我的 JS 正则表达式并不是那么出色,当我对内容中可能包含的内容一无所知时,我对给出正则表达式示例持双重警惕 :-) (比如,身体可能有包含'>'的属性)但愿意尝试..
【解决方案4】:

为什么不试试这个,看看会发生什么:

$('#testDiv').load('ajaxtest-load.html #wrapper', function(resp) {
    alert(resp);
});

来自$.load documentation

在 jQuery 1.2 中,您现在可以指定一个 URL 中的 jQuery 选择器。这样做 将过滤传入的 HTML 文档,只注入元素 匹配选择器。

【讨论】:

  • 谢谢,但是运行它,firebug 显示错误 '$.load' is not a function。
  • 你不能只使用 $.load。你必须在像 $(selector).load() 这样的选择器上使用它
  • @T B - 是的,不知道我在想什么。 @threebttn 抱歉,请尝试使用它来填充 div。查看我的编辑。
  • 我修改它以填充一个 div,但仍然没有运气。我认为这是因为它是一个完整的 HTML DOM 而不是 HTML sn-p(也根据下面的答案)。这可能是问题吗?如何解析完整的 HTML DOM?
  • 嗯,不确定从哪个活动中收到警报(SO 的新手),所以我将评论主要问题。我在下面用 parseHTML 函数更新了我的帖子,希望对您有所帮助
猜你喜欢
  • 1970-01-01
  • 2012-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-06
  • 2011-08-14
相关资源
最近更新 更多