2008-12-03 11 views
30

Necesito editar (usando javascript) un documento SVG incrustado en una página html.¿Cómo comprobar si un documento SVG incrustado está cargado en una página html?

Cuando se carga el SVG, puedo acceder al dom del SVG y sus elementos. Pero no puedo saber si el SVG dom está listo o no, así que no puedo realizar acciones predeterminadas en el SVG cuando se carga la página html.

Para acceder al DOM SVG, utilizo este código:

var svg = document.getElementById("chart").getSVGDocument(); 

donde "carta" es el id del elemento de inserción.

Si intento acceder a la SVG cuando el documento html está listo, de esta manera:

jQuery(document).ready(function() { 
var svg = document.getElementById("chart").getSVGDocument(); 
... 

SVG es siempre nula. Solo necesito saber cuándo no es nulo, entonces puedo comenzar a manipularlo. ¿Sabes si hay una manera de hacerlo?

+0

eliminado etiqueta incrustada – Ilya

Respuesta

-5

Usted podría tratar de votación De vez en cuando.

function checkReady() { 
    var svg = document.getElementById("chart").getSVGDocument(); 
    if (svg == null) { 
     setTimeout("checkReady()", 300); 
    } else { 
     ... 
    } 
} 
+0

Sí, funciona. No pensé en la solución de tiempo de espera ... Gracias, amigo. – alexmeia

+21

El sondeo no es una buena forma de hacerlo. Use un detector de eventos 'load' en su lugar. –

+0

@ ErikDahlström 'load' event listener tiene problemas. – Flimm

0

Puede asignar un controlador de eventos onload a un elemento dentro de su documento SVG y hacer que invoque una función javascript en la página html. cargar mapas a SVGLoad.

http://www.w3.org/TR/SVG11/interact.html#LoadEvent

El evento se dispara en el punto en el que el agente de usuario ha analizado totalmente el elemento y sus descendientes y está listo para actuar adecuadamente sobre ese elemento

+0

No, no puedo editar el documento SVG. Solo puedo manipularlo cuando está en la página web. – alexmeia

22

En su elemento de incrustación (por ejemplo 'Insertar', 'objeto', 'iframe') en el documento principal añadir un atributo onload que llama a su función, o añadir el detector de eventos en escritura, por ejemplo embeddingElm.addEventListener('load', callbackFunction, false). Otra opción podría ser escuchar DOMContentLoaded, depende de lo que desee.

También puede agregar un oyente de carga en el documento principal. jQuery(document).ready no significa que todos los recursos están cargados, solo que el documento en sí tiene un DOM que está listo para la acción. Sin embargo, tenga en cuenta que si escucha la carga del documento completo, no se invocará su función de devolución de llamada hasta que se carguen todos los recursos del documento, css, javascript, etc.

Si usa svg en línea, entonces jQuery(document).ready funcionará bien sin embargo.

En una nota adicional es posible que desee considerar el uso de embeddingElm.contentDocument (si está disponible) en lugar de embeddingElm.getSVGDocument().

+2

embeddingElm.addEventListener ('load', callbackFunction, false) no funcionará si EmbeddingElm ya está cargado cuando se ejecuta el script. DOMContentLoaded no funcionará si vincula una imagen en SVG (como una imagen de fondo). Usted (no debería) querer hacer: algo similar a: window.onload tampoco, porque entonces tendría que esperar hasta que todos sus recursos externos se hayan descargado también (como el seguimiento de scripts y anuncios, por ejemplo) – jBoive

+0

¿También sabe? cómo activar este detector de eventos de carga en el objeto SVG en una prueba angular? –

+0

En Safari, si el contenido SVG ya está cargado, 'load' nunca se desencadena. – Flimm

2

Usando jQuery se puede enlazar con el evento de carga de la ventana Erik menciona con:

$(window).load(function(){ 
    var svg = document.getElementById("chart").getSVGDocument(); 
}); 
+2

Creo que de esta forma se puede saber cuándo se carga el objeto SVG en la página html, pero aún no se sabe si el DOM del SVG está listo. – alexmeia

+0

Me pareció que esto funcionaba cuando estaba incorporando jquery dentro de un SVG autónomo, ¡gracias! – Vadi

8

Asumiendo que su SVG se encuentra en una etiqueta <embed>:

<embed id="embedded-image" src="image.svg" type="image/svg+xml" /> 

La imagen SVG es esencialmente en una sub documento que tendrá un evento load por separado al del document principal.Sin embargo, se puede detectar este evento y manejarlo:

var embed = document.getElementById("embedded-image"); 
embed.addEventListener('load', function() 
{ 
    var svg = embed.getSVGDocument(); 
    // Operate upon the SVG DOM here 
}); 

Esto es mejor que el sondeo como cualquier modificación que realice a la SVG va a pasar antes de que se pinta en primer lugar, la reducción de la pintura pasó el parpadeo y la CPU esfuerzo.

+0

Para operar con JQuery en el elemento dado, haz algo así: var svg = $ (embed.getSVGDocument(). DocumentElement); – BasTaller

3

El evento de carga del elemento de inserción (por ejemplo, objeto) sería mi preferencia pero, si esa no es una solución viable por alguna razón, la única prueba genérica y confiable que he encontrado para SVG DOM listo es getCurrentTime método del elemento raíz SVG:

var element = document.getElementById('elementId'); 
var svgDoc = element.contentDocument; 
var svgRoot = svgDoc ? svgDoc.rootElement : null; 

if (svgRoot 
    && svgRoot.getCurrentTime 
    && (svgRoot.getCurrentTime() > 0)) 
{ 
    /* SVG DOM ready */ 
} 

los estados que W3C SVG recommendation getCurrentTime en una SVGSVGElement:

devuelve la hora actual en segundos con respecto a la hora de inicio del fragmento de documento SVG actual. Si se llama a getCurrentTime antes de que comience la línea de tiempo del documento (por ejemplo, mediante una secuencia de comandos que se ejecuta en un elemento 'script' antes de enviar el evento SVGLoad del documento), se devuelve 0.

9

Se podría utilizar un caso proceso de carga para el registro.

some.svg Supongamos que está incrustado en etiqueta de objeto:

<body>  
<object id="svgholder" data="some.svg" type="image/svg+xml""></object> 
</body> 

Jquery

var svgholder = $('body').find("object#svgholder"); 

svgholder.load("image/svg+xml", function() { 
    alert("some svg loaded"); 
}); 

javascript

var svgholder = document.getElementById("svgholder"); 

svgholder.onload = function() { 
    alert("some svg loaded"); 
} 
+1

** Nota: ** Considere usar 'addEventListener ('load', handler)' en lugar de establecer la propiedad 'onload' para asegurarse de no anular otros manejadores de carga. Sin embargo, esto no es compatible con navegadores antiguos. ** Pregunta: ** La 'carga' de jQuery fue el primer método que traté de usar, pero sin el''imagen/svg + xml'' como primer argumento, no funcionará. ¿Puedes explicar esta magia?No pude encontrar una explicación en la documentación de jQuery. Simplemente menciona el argumento como 'url' (y aquí damos un tipo MIME). Y, nuevamente, ¿por qué no necesitamos tal cosa para 'onload'? – Neon

+0

Creo que es seguro decir que si está asumiendo que el navegador puede mostrar SVG incrustados, puede estar seguro de que implementa 'addEventListener' también. – Niavlys

+1

'svgholder.load (" image/svg + xml ", function() ...' parece estar invocando la carga jquery ajax en su lugar. Antes de v3.0, jquery determinaba qué carga llamar en función de los argumentos provistos. una cadena en el primer argumento, jquery intenta hacer un GET para 'imagen/svg + xml' como una url. Como coloca el contenido cargado en el elemento seleccionado, luego llama a la devolución de llamada proporcionada, esto podría parecer que funciona como una carga notificación, pero está haciendo otra cosa. Busque un 404 en su consola. Además, el controlador de eventos .load está en desuso a partir de 3.0. – Mnebuerquo

Cuestiones relacionadas