Простой пример 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-код документ, только вводящие элементы которые соответствуют селектору.