div color attribute javascript jquery ajax document-body

javascript - color - Buscar etiqueta de cuerpo en una respuesta HTML ajax



title html (4)

Estoy haciendo una llamada ajax para buscar contenido y agregar este contenido de esta manera:

$(function(){ var site = $(''input'').val(); $.get(''file.php'', { site:site }, function(data){ mas = $(data).find(''a''); mas.map(function(elem, index) { divs = $(this).html(); $(''#result'').append('''' + divs + ''''); }) }, ''html''); });

El problema es que cuando cambio a body no obtengo nada (no hay error, simplemente no html). Im asumiendo que el cuerpo es una etiqueta al igual que ''a'' es? ¿Qué estoy haciendo mal?

Así que esto funciona para mí:

mas = $(data).find(''a'');

Pero esto no lo hace:

mas = $(data).find(''body'');


El análisis del HTML devuelto a través de un objeto jQuery (es decir, $(data) ) para obtener la etiqueta del body está condenado al fracaso, me temo.

El motivo es que los data devueltos son una string (intente console.log(typeof(data)) ). Ahora, de acuerdo con la documentación de jQuery , al crear un objeto jQuery a partir de una cadena que contiene un marcado HTML complejo, es probable que se eliminen etiquetas como body . Esto sucede porque para crear el objeto, el marcado HTML se inserta realmente en el DOM que no puede permitir tales etiquetas adicionales.

Cita relevante de la documentación :

Si se pasa una cadena como parámetro a $ (), jQuery examina la cadena para ver si se parece a HTML.

[...] Si el HTML es más complejo que una sola etiqueta sin atributos, como se muestra en el ejemplo anterior, la creación real de los elementos se realiza mediante el mecanismo internoHTML del navegador. En la mayoría de los casos, jQuery crea un nuevo elemento y establece la propiedad innerHTML del elemento al fragmento HTML que se pasó. Cuando el parámetro tiene una etiqueta única (con etiqueta de cierre opcional o cierre rápido) - $ ("<img / > ") o $ (" <img> "), $ (" <a> </ a> ") o $ (" <a> ") - jQuery crea el elemento utilizando la función createElement () de JavaScript.

Al pasar en HTML complejo, algunos navegadores pueden no generar un DOM que replique exactamente el origen HTML proporcionado. Como se mencionó, jQuery usa la propiedad .innerHTML del navegador para analizar el HTML pasado e insertarlo en el documento actual. Durante este proceso, algunos navegadores filtran ciertos elementos como los elementos <html>, <title> o <head> Como resultado, los elementos insertados pueden no ser representativos de la cadena original pasada.


Experimenté un poco, y he identificado la causa hasta cierto punto, por lo que, en espera de una respuesta real que me interese, aquí hay un truco para ayudar a entender el problema.

$.get(''/'',function(d){ // replace the `HTML` tags with `NOTHTML` tags // and the `BODY` tags with `NOTBODY` tags d = d.replace(/(<//?)html( .+?)?>/gi,''$1NOTHTML$2>'',d) d = d.replace(/(<//?)body( .+?)?>/gi,''$1NOTBODY$2>'',d) // select the `notbody` tag and log for testing console.log($(d).find(''notbody'').html()) })

Edición: más experimentación

Parece que es posible si carga el contenido en un iframe, luego puede acceder al contenido del marco a través de alguna jerarquía de objetos dom ...

// get a page using AJAX $.get(''/'',function(d){ // create a temporary `iframe`, make it hidden, and attach to the DOM var frame = $(''<iframe id="frame" src="/" style="display: none;"></iframe>'').appendTo(''body'') // check that the frame has loaded content $(frame).load(function(){ // grab the HTML from the body, using the raw DOM node (frame[0]) // and more specifically, it''s `contentDocument` property var html = $(''body'',frame[0].contentDocument).html() // check the HTML console.log(html) // remove the temporary iframe $("#frame").remove() }) })

Edición: más investigación

Parece que contentDocument es la forma que cumple con los estándares para controlar el elemento window.document de un iFrame, pero, por supuesto, a IE no le importan los estándares, así que esta es la forma de obtener una referencia a window.document.body de iFrame window.document.body Objeto de forma multiplataforma ...

var iframeDoc = iframe.contentDocument || iframe.contentWindow.document; var iframeBody = iframeDoc.body; // or for extra caution, to support even more obsolete browsers // var iframeBody = iframeDoc.getElementsByTagName("body")[0]

Ver: contentDocument para un iframe


Me di cuenta de algo maravilloso (¡Creo!)

¿Tienes tu html como una cadena?

var results = //probably an ajax response

Aquí hay un objeto jquery que funcionará exactamente igual que los elementos actualmente conectados al DOM:

var superConvenient = $($.parseXML(response)).children(''html'');

¡Nada será despojado de superConvenient ! Puedes hacer cosas como superConvenient.find(''body'') o incluso

superConvenient.find(''head > script'');

superConvenient funciona exactamente como los elementos de jquery a los que todos superConvenient acostumbrados!

NOTA

En este caso, los results la cadena deben ser XML válidos porque se alimentan al método parseXML de JQuery. Una característica común de una respuesta HTML puede ser una etiqueta <!DOCTYPE> , que invalidaría el documento en este sentido. <!DOCTYPE> posible que las etiquetas <!DOCTYPE> deban eliminarse antes de utilizar este enfoque! También tenga en cuenta las características como <!--[if IE 8]>...<![endif]--> , etiquetas sin etiquetas de cierre, por ejemplo:

<ul> <li>content... <li>content... <li>content... </ul>

... y cualquier otra característica de HTML que será interpretada con indulgencia por los navegadores, pero bloqueará el analizador XML.


Terminé con esta solución simple:

var body = data.substring(data.indexOf("<body>")+6,data.indexOf("</body>")); $(''body'').html(body);

Funciona también con cabeza o cualquier otra etiqueta .

(Una solución con análisis xml sería mejor, pero con una respuesta XML no válida, debe realizar un "análisis de cadena").