Простой пример jQuery ajax не находит элементы в возвращенном HTML

Я пытаюсь изучить функции 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. Что я делаю не так?

EDIT: я загружаю "ajaxtest-load.html", который включает весь заголовок, включая jquery. Это проблема?

Ответ 1

Мне удалось полностью загрузить фрагменты из полных html-документов, используя .load().

Чтобы создать новый блок с извлеченным html в DOM, я делаю это:

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

Если он не работает для вас, убедитесь, что вы используете самую последнюю версию (или сообщение 1.2) jQuery. Подробнее см. Документацию для .load.

Edit:

Обратите внимание, что в приведенном выше примере результат будет:

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

Чтобы получить только содержимое div #contents в другом документе, используйте функцию обратного вызова в вызове функции загрузки.

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

Ответ 2

Это не прямой ответ, но может помочь прояснить ситуацию.

Параметр данных функции обратного вызова может быть превращен в объект jQuery (1.6.2) $(data), который содержит различные части ответа HTML:

  • Материал, который предшествует фактическому документу, например объявление doctype, или неосведомленные текстовые поля пробела.
  • Содержимое элемента head.
  • Содержимое элемента body.

Элементы html, 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 элементы заголовка не являются частью $(данных). Я понятия не имею, почему это так.

Ответ 3

Я обнаружил, что если ajaxtest-load.html не имеет тегов <html> или <body> , а всего несколько элементов html, он работает.

Edit:

Если входной файл должен быть полной 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;
}

Это работает?

Ответ 4

Почему бы не попробовать это и посмотреть, что произойдет:

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

Из $. загрузить документацию:

В jQuery 1.2 вы можете указать Селектор jQuery в URL-адресе. Делать это будет фильтровать входящий HTML-код документ, только вводящие элементы которые соответствуют селектору.