在jQuery ajax调用以检索整个XHTML文档之后,从结果字符串中选择特定元素的最佳方法是什么?也许有一个库或插件可以解决这个问题?
jQuery只能选择存在于字符串中的XHTML元素,如果它们通常在W3C规范中的div中被允许的话;因此,我很想选择<title>
,<script>
和<style>
等内容。
根据jQuery文档:
http://docs.jquery.com/Core/jQuery#htmlownerDocument
HTML字符串不能包含 一个无效的元素 div,例如html,head,body或 标题要素。
因此,既然我们已经确定jQuery没有提供这样做的方法,我将如何选择这些元素?例如,如果您可以告诉我如何选择远程页面的标题,那将是完美的!
谢谢,皮特
答案 0 :(得分:29)
我建议你退出jQuery并使用原始XML dom方法,而不是黑客攻击jQuery。使用XML Dom方法,您可以这样做:
window.onload = function(){
$.ajax({
type: 'GET',
url: 'text.html',
dataType: 'html',
success: function(data) {
//cross platform xml object creation from w3schools
try //Internet Explorer
{
xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async="false";
xmlDoc.loadXML(data);
}
catch(e)
{
try // Firefox, Mozilla, Opera, etc.
{
parser=new DOMParser();
xmlDoc=parser.parseFromString(data,"text/xml");
}
catch(e)
{
alert(e.message);
return;
}
}
alert(xmlDoc.getElementsByTagName("title")[0].childNodes[0].nodeValue);
}
});
}
没有搞乱iframe等。
答案 1 :(得分:5)
只有一个想法 - 在FF / Safari中测试 - 如果您创建一个iframe临时存储文档似乎也有效。当然,如果你这样做,那么只使用iframe的src属性来加载文档并在它的“onload”中做你想做的事情可能会更聪明。
$(function() {
$.ajax({
type: 'GET',
url: 'result.html',
dataType: 'html',
success: function(data) {
var $frame = $("<iframe src='about:blank'/>").hide();
$frame.appendTo('body');
var doc = $frame.get(0).contentWindow.document;
doc.write(data);
var $title = $("title", doc);
alert('Title: '+$title.text() );
$frame.remove();
}
});
});
我必须将iframe附加到正文以使其拥有.contentWindow。
答案 2 :(得分:3)
受到this answer的启发,但推迟了:
function fetchDoc(url) {
var dfd;
dfd = $.Deferred();
$.get(url).done(function (data, textStatus, jqXHR) {
var $iframe = $('<iframe style="display:none;"/>').appendTo('body');
var $doc = $iframe.contents();
var doc = $doc[0];
$iframe.load(function() {
dfd.resolveWith(doc, [data, textStatus, jqXHR]);
return $iframe.remove();
});
doc.open();
doc.write(data);
return doc.close();
}).fail(dfd.reject);
return dfd.promise();
};
用它吸烟:
fetchDoc('/foo.html').done(function (data, textStatus, jqXHR) {
alert($('title', this).text());
});
LIVE DEMO(点击“运行”)
答案 3 :(得分:2)
一些快速标签重命名怎么样?
$.ajax({
type : "GET",
url : 'results.html',
dataType : "html",
success: function(data) {
data = data.replace(/html/g, "xhtmlx");
data = data.replace(/head/g, "xheadx");
data = data.replace(/title/g, "xtitlex");
data = data.replace(/body/g, "xbodyx");
alert($(data).find("xtitlex").text());
}
});
答案 4 :(得分:2)
这很有效。我只是拆开了构建块以提高可读性。
检查说明和内联注释,以掌握其工作原理以及为什么必须这样做。
当然,这不能用于检索跨域内容,因为您必须通过您的脚本代理调用,或者考虑像flXHR (Cross-Domain Ajax with Flash)这样的集成
<强> call.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" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>asd</title>
<script src="jquery.js" type="text/javascript"></script>
<script src="xmlDoc.js" type="text/javascript"></script>
<script src="output.js" type="text/javascript"></script>
<script src="ready.js" type="text/javascript"></script>
</head>
<body>
<div>
<input type="button" id="getit" value="GetIt" />
</div>
</body>
</html>
jquery.js 是(jQuery 1.3.2未压缩) test.html 有效的XHTML文档
<强> xmlDoc.js 强>
// helper function to create XMLDocument out of a string
jQuery.createXMLDocument = function( s ) {
var xmlDoc;
// is it a IE?
if ( window.ActiveXObject ) {
xmlDoc = new ActiveXObject('Microsoft.XMLDOM');
xmlDoc.async = "false";
// prevent erros as IE tries to resolve the URL in the DOCTYPE
xmlDoc.resolveExternals = false;
xmlDoc.validateOnParse = false;
xmlDoc.loadXML(s);
} else {
// non IE. give me DOMParser
// theoretically this else branch should never be called
// but just in case.
xmlDoc = ( new DOMParser() ).parseFromString( s, "text/xml" );
}
return xmlDoc;
};
<强> output.js 强>
// Output the title of the loaded page
// And get the script-tags and output either the
// src attribute or code
function headerData(data) {
// give me the head element
var x = jQuery("head", data).eq(0);
// output title
alert(jQuery("title", x).eq(0).text());
// for all scripttags which include a file out put src
jQuery("script[src]", x).each(function(index) {
alert((index+1)+" "+jQuery.attr(this, 'src'));
});
// for all scripttags which are inline javascript output code
jQuery("script:not([src])", x).each(function(index) {
alert(this.text);
});
}
<强> ready.js 强>
$(document).ready(function() {
$('#getit').click(function() {
$.ajax({
type : "GET",
url : 'test.html',
dataType : "xml",
// overwrite content-type returned by server to ensure
// the response getst treated as xml
beforeSend: function(xhr) {
// IE doesn't support this so check before using
if (xhr.overrideMimeType) {
xhr.overrideMimeType('text/xml');
}
},
success: function(data) {
headerData(data);
},
error : function(xhr, textStatus, errorThrown) {
// if loading the response as xml failed try it manually
// in theory this should only happen for IE
// maybe some
if (textStatus == 'parsererror') {
var xmlDoc = jQuery.createXMLDocument(xhr.responseText);
headerData(xmlDoc);
} else {
alert("Failed: " + textStatus + " " + errorThrown);
}
}
});
});
});
在Opera中,整个过程没有createXMLDocument
和beforeSend
函数。
Firefox(3.0.11)和IE6(无法测试IE7,IE8,其他浏览器)需要额外的技巧,因为当服务器返回的Content-Type:
未指示时,它们会出现问题它是xml。我的网络服务器返回Content-Type: text/html; charset=UTF-8
test.html.
在这两个浏览器中,jQuery使用error
调用textStatus
回调parsererror
。因为在jQuery.js中的第3706行
data = xml ? xhr.responseXML : xhr.responseText;
data
被设置为null。与在FF和IE中一样,xhr.responseXML
为空。发生这种情况是因为他们没有得到返回的数据是xml(正如Opera所做的那样)。只有xhr.responseText
与整个xhtml代码一起设置。由于数据为零,因此第3708行
if ( xml && data.documentElement.tagName == "parsererror" )
抛出一个异常,该异常在第3584行中捕获,状态设置为parsererror
。
在FF中,我可以在发送请求之前使用overrideMimeType()
函数解决问题。
但IE不支持XMLHttpRequest-object上的该函数,因此如果运行错误回调并且错误为parsererror
,我必须自己生成XMLDocument。
test.html的例子
<?xml version="1.0" encoding="UTF-8" ?>
<!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" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Plugins | jQuery Plugins</title>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">var imagePath = '/content/img/so/';</script>
</head>
<body>
</body>
</html>
答案 5 :(得分:1)
从我的另一个答案(Simple jQuery ajax example not finding elements in returned HTML)无耻地复制和改编,这将获取远程页面的HTML,然后parseHTML函数为它创建一个临时div元素并将批次放入其中,贯穿它,并返回请求的元素。然后jQuery警告里面的text()。
$(document).ready(function(){
$('input').click(function(){
$.ajax({
type : "POST",
url : 'ajaxtestload.html',
dataType : "html",
success: function(data) {
alert( data ); // shows whole dom
var gotcha = parseHTML(data, 'TITLE'); // nodeName property returns uppercase
if (gotcha) {
alert($(gotcha).html()); // returns null
}else{
alert('Tag not found.');
}
},
error : function() {
alert("Sorry, The requested property could not be found.");
}
});
});
});
function parseHTML(html, tagName) {
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].nodeName == tagName) {
return allChilds[i];
}
}
return false;
}
要获得几个项目或脚本标签列表,比方说,我认为你必须改进parseHTML功能,但是嘿 - 概念证明: - )
答案 6 :(得分:0)
如果你想找到特定命名字段的值(即表单中的输入),可以找到适合你的字段:
var fields = ["firstname","surname", ...."foo"];
function findFields(form, fields) {
var form = $(form);
fields.forEach(function(field) {
var val = form.find("[name="+field+"]").val();
....
答案 7 :(得分:0)
这个怎么样:Load XML from string
答案 8 :(得分:0)
将XML字符串解析为XML DOM
后,我会直接使用jQuery
(您可以通过向jQUery
选择器提供上下文来完成此操作,例如{ {1}}或使用$(':title', xdoc.rootElement)
(适用于Firefox;据说可能是IE的库,但我没有取得很好的成功)。
答案 9 :(得分:0)
$.get('yourpage.html',function(data){
var content = $('<div/>').append(data).find('#yourelement').html();
});
你也可以简单地暂时包装在一个div中。您甚至不需要将其添加到DOM中。