javascript - queryselectorall - jQuery.find() no devuelve datos en IE pero sí en Firefox y Chrome
innerhtml (15)
Ayudé a un amigo haciendo un pequeño trabajo web para él. Parte de lo que necesitaba era una forma fácil de cambiar un par de textos en su sitio. En lugar de tener que editar el código HTML, decidí proporcionar un archivo XML con los mensajes y usé jQuery para sacarlos del archivo e insertarlos en la página.
Funciona muy bien ... En Firefox y Chrome, no tan genial en IE7. Esperaba que uno de ustedes pudiera decirme por qué. Hice una feria pero de google pero no pude encontrar lo que estoy buscando.
Aquí está el XML:
<?xml version="1.0" encoding="utf-8" ?>
<messages>
<message type="HeaderMessage">
This message is put up in the header area.
</message>
<message type="FooterMessage">
This message is put in the lower left cell.
</message>
</messages>
Y aquí está mi llamada jQuery:
<script type="text/javascript">
$(document).ready(function() {
$.get(''messages.xml'', function(d) {
//I have confirmed that it gets to here in IE
//and it has the xml loaded.
//alert(d); gives me a message box with the xml text in it
//alert($(d).find(''message'')); gives me "[object Object]"
//alert($(d).find(''message'')[0]); gives me "undefined"
//alert($(d).find(''message'').Length); gives me "undefined"
$(d).find(''message'').each(function() {
//But it never gets to here in IE
var $msg = $(this);
var type = $msg.attr("type");
var message = $msg.text();
switch (type) {
case "HeaderMessage":
$("#HeaderMessageDiv").html(message);
break;
case "FooterMessage":
$("#footermessagecell").html(message);
break;
default:
}
});
});
});
</script>
¿Hay algo que deba hacer de manera diferente en IE? Basado en el cuadro de mensaje con [object Object], se supone que .find estaba funcionando en IE pero dado que no puedo indexar en la matriz con [0] o verificar su longitud, supongo que eso significa que .find no está devolviendo cualquier resultado ¿Alguna razón por la que eso funcionaría perfectamente en Firefox y Chrome, pero fallaría en IE?
Soy un novato total con jQuery, así que espero no haber hecho algo estúpido. El código anterior fue sacado de un foro y modificado para satisfacer mis necesidades. Como jQuery es multiplataforma, pensé que no tendría que lidiar con este desastre.
Editar: he encontrado que si cargo la página en Visual Studio 2008 y la ejecuto, funcionará en IE. Entonces resulta que siempre funciona cuando se ejecuta a través del servidor web de desarrollo. Ahora estoy pensando en que IE simplemente no le gusta hacer .find en XML cargado fuera de mi unidad local así que tal vez cuando esté en un servidor web real funcionará bien.
He confirmado que funciona bien cuando se navega desde un servidor web. Debe ser una peculiaridad con IE. Supongo que es porque el servidor web establece el tipo de mimo para la transferencia de archivos de datos xml y sin eso IE no analiza correctamente el xml.
A veces IE lee saltos de línea como nodos adicionales. Intente eliminar el espacio en blanco adicional hasta las etiquetas, o intente encerrarlo como CDATA.
Cambiar el siguiente contenido
dataType :"text/xml",
a
dataType :"xml",
No es necesario cambiar el find ().
Dado que el problema de IE es que el analizador xml ahoga los archivos xml que no se transmiten utilizando el encabezado "text / xml" correcto, puede incluir un poco de código en el evento completo de Ajax :
complete: function( xhr, status ) { alert( "COMPLETE. You got:/n/n" + xhr.responseText ) ; if( status == ''parsererror'' ) { alert( "There was a PARSERERROR. Luckily, we know how to fix that./n/n" + "The complete server response text was " + xhr.responseText ) ; xmlDoc = null; // Create the xml document from the responseText string. // This uses the w3schools method. // see also if( window.DOMParser ) { parser=new DOMParser(); xmlDoc=parser.parseFromString( xhr.responseText,"text/xml" ) ; } else // Internet Explorer { xmlDoc=new ActiveXObject( "Microsoft.XMLDOM" ) ; xmlDoc.async = "false" ; xmlDoc.loadXML( xhr.responseText ) ; } $( ''#response'' ).append( ''<p>complete event/xmlDoc: '' + xmlDoc + ''</p>'' ) ; $( ''#response'' ).append( ''<p>complete event/status: '' + status + ''</p>'' ) ; processXMLDoc( xmlDoc ) ; } },
aquí hay un ejemplo más completo
<!DOCTYPE html> <html> <head> <title>Reading XML with jQuery</title> <style> #response { border: solid 1px black; padding: 5px; } </style> <script src="jquery-1.3.2.min.js"></script> <script> function processXMLDoc( xmlDoc ) { var heading = $(xmlDoc).find(''heading'').text() ; $( ''#response'' ).append( ''<h1>'' + heading + ''</h1>'' ) ; var bodyText = $(xmlDoc).find(''body'').text() ; $( ''#response'' ).append( ''<p>'' + bodyText + ''</p>'' ) ; } $(document).ready(function() { jQuery.ajax({ type: "GET", url: "a.xml", // ! watch out for same // origin type problems dataType: "xml", // ''xml'' passes it through the browser''s xml parser success: function( xmlDoc, status ) { // The SUCCESS EVENT means that the xml document // came down from the server AND got parsed successfully // using the browser''s own xml parsing caps. processXMLDoc( xmlDoc ); // IE gets very upset when // the mime-type of the document that // gets passed down isn''t text/xml. // If you are missing the text/xml header // apparently the xml parse fails, // and in IE you don''t get to execute this function AT ALL. }, complete: function( xhr, status ) { alert( "COMPLETE. You got:/n/n" + xhr.responseText ) ; if( status == ''parsererror'' ) { alert( "There was a PARSERERROR. Luckily, we know how to fix that./n/n" + "The complete server response text was " + xhr.responseText ) ; xmlDoc = null; // Create the xml document from the responseText string. // This uses the w3schools method. // see also if( window.DOMParser ) { parser=new DOMParser(); xmlDoc=parser.parseFromString( xhr.responseText,"text/xml" ) ; } else // Internet Explorer { xmlDoc=new ActiveXObject( "Microsoft.XMLDOM" ) ; xmlDoc.async = "false" ; xmlDoc.loadXML( xhr.responseText ) ; } $( ''#response'' ).append( ''<p>complete event/xmlDoc: '' + xmlDoc + ''</p>'' ) ; $( ''#response'' ).append( ''<p>complete event/status: '' + status + ''</p>'' ) ; processXMLDoc( xmlDoc ) ; } }, error: function( xhr, status, error ) { alert( ''ERROR: '' + status ) ; alert( xhr.responseText ) ; } }); }); </script> </head> <body> <div> <h1><a href="http://think2loud.com/reading-xml-with-jquery/">Reading XML with jQuery</a></h1> <p> <a href="http://docs.jquery.com/Ajax/jQuery.ajax#options">#1 jQuery.ajax ref</a> </p> </div> <p>Server says:</p> <pre id="response"> </pre> </body> </html>
contenido de a.xml
<?xml version="1.0"?> <note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don''t forget me this weekend!</body> </note>
Extiende este ejemplo .
El tipo de datos: "xml" no soluciona este problema en IE8, sino que pasa por una expección "TypeError".
La solución rápida y sucia consiste en ajustar la respuesta xml en un elemento html, como div:
$("<div>" + xml + "</div>").find("something");
(funciona en todos los navegadores)
Me encontré con el mismo problema cuando estaba recuperando datos de un documento XML. Después de buscar en Google mucho en Internet, surgió la búsqueda de este sitio web, pero sin una respuesta adecuada al problema. Pero una respuesta me ayudó a resolver el problema:
"Dado que el problema de IE es que el analizador xml ahoga los archivos xml que no se transmiten utilizando el encabezado correcto" text / xml ", puede incluir un poco de código en el evento completo de Ajax:"
He identificado dos problemas con IE al hacer las llamadas $ .ajax (...) y $ .get (...):
El valor del parámetro xml debe estar en mayúscula (''XML'' no ''xml'') para ambas llamadas - $ .ajax (..., dataType: "XML") y $ .get (xmlDataFilePath, function (d) {.. .}, "xml")
Cuando la llamada ajax tiene éxito, el argumento xml de la función de devolución de llamada es en realidad una cadena, no un objeto DOM XML
El segundo problema se resuelve de esta manera:
$(document).ready(function()
{
$.ajax(
{
type: "GET",
url: "messages.xml",
dataType: "XML", /* this parameter MUST BE UPPER CASE for it to work in IE */
success: function(xml)
{
processXmlDoc( createXmlDOMObject ( xml ) );
}, /* success: */
error: function(xhr, textStatus, errorThrown)
{
alert(textStatus + '' '' + errorThrown);
} /* error: */
});/* $.ajax */
function createXmlDOMObject(xmlString)
{
var xmlDoc = null;
if( ! window.DOMParser )
{
// the xml string cannot be directly manipulated by browsers
// such as Internet Explorer because they rely on an external
// DOM parsing framework...
// create and load an XML document object through the DOM
// ActiveXObject that it can deal with
xmlDoc = new ActiveXObject( "Microsoft.XMLDOM" );
xmlDoc.async = false;
xmlDoc.loadXML( xmlString );
}
else
{
// the current browser is capable of creating its own DOM parser
parser = new DOMParser();
xmlDoc = parser.parseFromString( xmlString, "text/xml" ) ;
}
return xmlDoc;
}
function processXmlDoc(xmlDoc)
{
// write here your XML processing logic for the document object...
}
}); // $(document).ready
Puede encontrar que si pasa el tipo de datos a su llamada de obtención, puede analizar correctamente XML. Las peculiaridades de IE podrían evitar que jQuery lo detecte automáticamente como XML, lo que da como resultado que se pase el tipo de datos incorrecto a la función de devolución de llamada.
<script type="text/javascript">
$(document).ready(function() {
$.get(''messages.xml'', function(d) {
//I have confirmed that it gets to here in IE
//and it has the xml loaded.
//alert(d); gives me a message box with the xml text in it
//alert($(d).find(''message'')); gives me "[object Object]"
//alert($(d).find(''message'')[0]); gives me "undefined"
//alert($(d).find(''message'').Length); gives me "undefined"
$(d).find(''message'').each(function() {
//But it never gets to here in IE
var $msg = $(this);
var type = $msg.attr("type");
var message = $msg.text();
switch (type) {
case "HeaderMessage":
$("#HeaderMessageDiv").html(message);
break;
case "FooterMessage":
$("#footermessagecell").html(message);
break;
default:
}
});
}, "xml");
});
</script>
EDITAR:
De hecho, acabo de experimentar .find () no funciona para un proyecto en ningún navegador, pero en su lugar pude utilizar .filter (). Es molesto que tuve que recurrir a esto, pero si funciona ...
$(d).filter(''message'').each(......);
Si el XML se genera mediante un script PHP, puede hacer
<?php
header("Content-type: text/xml");
echo ''<myxml></myxml>'';
?>
Entonces, el método de búsqueda funciona en todos los navegadores
También tuve el mismo problema al importar contactos de correo electrónico. Pude importar contactos y mostrar en todos los navegadores excepto en IE, ya que .find()
no funcionaba.
Entonces, asigné "text/xml"
a response.contentType
.
es decir, response.contentType = "text/xml"
y funcionó.
antes era "text/html"
También tuve un problema similar, pero solucioné el problema IE jQuery XML .find () usando el siguiente código.
Nota: Use .text () en lugar de .html ().
jQuery.ajax({
type: "GET",
url: "textxml.php",
success: function(msg){
data = parseXml(msg);
//alert(data);
var final_price = jQuery(data).find("price1").text();
alert(final_price);
}
});
function parseXml(xml) {
if (jQuery.browser.msie) {
var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.loadXML(xml);
xml = xmlDoc;
}
return xml;
}
Tengo el mismo problema...
Resuelto con esto:
http://www.w3schools.com/dom/dom_parser.asp
if (window.DOMParser)
{
parser=new DOMParser();
xmlDoc=parser.parseFromString(text,"text/xml");
}
else // Internet Explorer
{
xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async="false";
xmlDoc.loadXML(text);
}
úsalo para transformar tu var en objeto xml ...
Tu puedes hacer
<a>
<messages>
<message type="HeaderMessage">
This message is put up in the header area.
</message>
<message type="FooterMessage">
This message is put in the lower left cell.
</message>
</messages>
</a>
y use find (). Funciona para IE8 y para Firefox v.3.6.3
Tuve el mismo problema, estoy desarrollando una aplicación que está basada en la web, pero la necesito para implementarla fuera de línea, dentro de un CD. Encontré una solución en esta página que es la misma solución que se puede ver arriba http://docs.jquery.com/Specifying_the_Data_Type_for_AJAX_Requests y el código es muy simple:
$.ajax({
url: "data.xml",
dataType: ($.browser.msie) ? "text" : "xml",
success: function(data){
var xml;
if (typeof data == "string") {
xml = new ActiveXObject("Microsoft.XMLDOM");
xml.async = false;
xml.loadXML(data);
} else {
xml = data;
}
// write here your XML processing logic for the document object...
}
});
Verifica el tipo de contenido de la respuesta. Si obtiene messages.xml como el tipo de mime equivocado, Internet Explorer no lo analizará como XML.
Para verificar el tipo de contenido, necesita acceder al objeto XMLHttpRequest. La devolución de llamada de éxito normal no pasa como un parámetro, por lo que debe agregar un controlador de evento genérico ajaxComplete o ajaxSuccess. El segundo parámetro para esos eventos es el objeto XMLHttpRequest. Puede llamar al método getResponseHeader para obtener el tipo de contenido.
$(document).ajaxComplete(function(e, x) {
alert(x.getResponseHeader("Content-Type"));
});
Lamentablemente, no hay manera de que yo sepa en Internet Explorer para anular lo que envía el servidor, por lo que si es incorrecto necesita cambiar el servidor para enviar "text / xml" para el tipo de contenido.
Algunos navegadores tienen un método overrideMimeType
que puedes llamar antes de send
para forzarlo a usar "text / xml", pero Internet Explorer no lo admite hasta donde yo sé.
Está funcionando bien! Prueba esto,
Chrome / Firefox:
xml.children[0].childNodes[1].innerHTML;
IE8 + / Safari:
xml.childNodes[0].childNodes[1].textContent;
IE8:
xml.documentElement.childNodes[1].text;
Código de muestra aquí,
var xml = $.parseXML(XMLDOC);
Var xmlNodeValue = "";
if(userAgent.match("msie 8.0")){
xmlNodeValue = xml.children[0].childNodes[1].innerHTML;
}else{ // IE8+
xmlNodeValue = xml.childNodes[0].childNodes[1].textContent;
}
$.ajax({
url: ''messages.xml'',
success: function(data){
$(d).find(''message'').each(function(){
//But it never gets to here in IE
var $msg = $(this);
var type = $msg.attr("type");
var message = $msg.text();
switch (type) {
case "HeaderMessage":
$("#HeaderMessageDiv").html(message);
break;
case "FooterMessage":
$("#footermessagecell").html(message);
break;
}
});
},
dataType: ''xml''
});
Intente decirle a jQuery qué dataType está obteniendo para que use los métodos correctos para procesar su solicitud.