2010-02-20 10 views
7

Así que estoy agarrando feeds RSS a través de AJAX. Después de procesarlos, tengo una cadena html que quiero manipular usando varias funciones de jQuery. Para hacer esto, necesito un árbol de nodos DOM.construye un árbol DOM a partir de una cadena sin cargar recursos (específicamente imágenes)

Puedo analizar una cadena HTML en la función jQuery().
Puedo agregarlo como innerHTML a algún nodo oculto y usarlo.
Incluso he intentado usar el range.createContextualFragment() no estándar de mozilla.

El problema con todas estas soluciones es que cuando mi fragmento de HTML tiene una etiqueta <img>, Firefox obedientemente obtiene la imagen a la que se hace referencia. Debido a que este procesamiento es algo de fondo que no se muestra al usuario, me gustaría obtener un árbol DOM sin el navegador cargando todas las imágenes que contiene.

¿Es esto posible con javascript? No me importa si es solo mozilla, ya que estoy usando las funciones de JavaScript 1.7 (que parecen ser solo de mozilla por ahora)

Respuesta

3

La respuesta es la siguiente:

var parser = new DOMParser(); 
var htmlDoc = parser.parseFromString(htmlString, "text/html"); 
var jdoc = $(htmlDoc); 
console.log(jdoc.find('img')); 

Si se presta atención a sus peticiones web se dará cuenta de que ninguno se hizo a pesar de que la cadena HTML se analiza y se envolvió por jquery.

+0

Mejor tarde que nunca, buena respuesta :) – gfxmonk

+1

@gfxmonk: El problema con esto es que el análisis de HTML con 'DOMParser' no es compatible con nada anterior a IE10, y no es compatible con Safari en absoluto. IE10 finalmente agrega análisis de HTML, por lo que si la gente de Safari se uniera, podría ser viable en un par de años. Pero si sus navegadores de destino no incluyen Safari o IE8 o IE9, funciona. Jeromeyers: cuando hay problemas de soporte * significativos, siempre es mejor mencionarlos en la respuesta. –

+0

@ T.J.Crowder Gracias por la información. No estaba al tanto del problema de compatibilidad del navegador. Entonces, una extensión de navegador cruzada para jquery se parecería a su respuesta para navegadores antiguos y safari y mi respuesta para navegadores más nuevos. – jeromeyers

3

La respuesta obvia es analizar la cadena y eliminar los atributos src de img etiquetas (y similares para otros recursos externos que no desea cargar). Pero ya habrás pensado en eso y estoy seguro de que estás buscando algo menos problemático. También supongo que ya ha intentado eliminar el atributo src después de haber jquery analizar la cadena pero antes de anexarla al documento, y ha encontrado que las imágenes todavía se están solicitando.

No se me ocurre ninguna otra cosa, pero es posible que no necesites hacer un análisis completo; esta sustitución debe hacerlo en Firefox con algunas salvedades:

thestring = thestring.replace("<img ", "<img src='' "); 

Las advertencias:

  • Esto parece funcionar en el actual Firefox. Eso no significa que las versiones posteriores no elegirán manejar los atributos duplicados src de manera diferente.
  • Esto asume la cadena literal "suposición de propósito general, esa cadena podría aparecer en un valor de atributo en una página suficientemente ... interesante ... especialmente en un controlador onclick en línea como este: <a href='#' onclick='$("frog").html("<img src=\"spinner.gif\">")'> (Aunque en ese ejemplo, el reemplazo de falso positivo es inofensivo.)

Esto es obviamente un truco, pero en un ambiente limitado con datos razonablemente bien conocidos ...

+0

@T. J.- Tienes razón, funciona en todos los navegadores, excepto en Firefox, para ver si hay otra forma. También para hacer tuyos más robustos, sugiero simplemente 'src =' reemplazado por 'blah =', esto eliminaría también las búsquedas de JavaScript. –

+0

@Nick: El parse-then-remove funciona, excepto en FF? Je. Clásico, todo menos el único navegador que OP quería usar. :-) No traté de ensuciar con 'src =' porque hace * mucho * más complicado el reemplazo, tiene que estar seguro de que está apareciendo dentro de una etiqueta, etc., etc. –

+0

@ T.J. no no, mi solución funcionó en todas partes, excepto en FF, por lo que no vi, pero sí, la misma ironía :) –

3

puede utilizar el DOM parser para manipular los nodos. basta con sustituir los atributos src, almacenan sus originales valores y agregarlos más tarde.

muestra:

(function() { 
     var s = "<img src='http://www.google.com/logos/olympics10-skijump-hp.png' /><img src='http://www.google.com/logos/olympics10-skijump-hp.png' />"; 
     var parser = new DOMParser(); 
     var dom = parser.parseFromString("<div id='mydiv' >" + s + "</div>", "text/xml"); 
     var imgs = dom.getElementsByTagName("img"); 
     var stored = []; 
     for (var i = 0; i < imgs.length; i++) { 
      var img = imgs[i]; 
      stored.push(img.getAttribute("src")); 
      img.setAttribute("myindex", i); 
      img.setAttribute("src", null); 
     } 
     $(document.body).append(new XMLSerializer().serializeToString(dom)); 
     alert("Images appended"); 
     window.setTimeout(function() { 
      alert("loading images"); 
      $("#mydiv img").each(function() { 
       this.src = stored[$(this).attr("myindex")]; 
      }) 
      alert("images loaded"); 
     }, 2000); 
    })(); 
+0

Gracias, esa es una gran respuesta. El único problema (para mi caso) es que solo es compatible con XML válido, que probablemente no funcionará para contenido de fuentes RSS arbitrarias (como me gustaría). Pero para otros, si puede garantizar el XML válido, debe usar esto;) – gfxmonk

+0

"Es muy fácil analizar los canales RSS con Javascript, ya que los canales RSS son simplemente XML". Desde "Analizando las fuentes RSS con AJAX/Javascript": http://www.captain.at/howto-ajax-parse-rss.php :-) –

+0

sí, la fuente RSS es XML válido. Sin embargo, el contenido de la entrada es solo CDATA que contiene el mish-mash de HTML que el autor publicó como el "contenido" de la entrada. Esa es (lamentablemente) la parte que deseo analizar. – gfxmonk

Cuestiones relacionadas