javascript - arc - ¿Cómo verificar si un documento SVG incrustado está cargado en una página html?
svg stroke (7)
Necesito editar (usando javascript) un documento SVG incrustado en una página html.
Cuando el SVG está cargado, 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 a SVG dom, uso este código:
var svg = document.getElementById("chart").getSVGDocument();
donde "gráfico" es la identificación del elemento de inserción.
Si trato de acceder al SVG cuando el documento html está listo, de esta manera:
jQuery(document).ready( function() {
var svg = document.getElementById("chart").getSVGDocument();
...
svg es siempre nulo. Solo necesito saber cuándo no es nulo, entonces puedo comenzar a manipularlo. ¿Sabes si hay una manera de hacerlo?
Podría usar un evento de carga para el control.
Supongamos que some.svg está incrustado en la 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");
}
El evento de carga del elemento de inserción (por ejemplo, el 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 el método getCurrentTime del SVG elemento raíz:
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 */
}
La recomendación W3C SVG establece que getCurrentTime en un SVGSVGElement:
Devuelve la hora actual en segundos relativa a la hora de inicio para el 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.
En su elemento de incrustación (por ejemplo, ''incrustación'', ''objeto'', ''iframe'') en el documento principal, agregue un atributo onload
que llame a su función o agregue el detector de eventos en una secuencia de comandos, 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 de todo el documento, no se invocará su función de devolución de llamada hasta que se carguen todos los recursos de ese documento, css, javascript, etc.
Si usas svg en línea, entonces jQuery(document).ready
funcionará sin problemas.
En una nota adicional, quizás desee considerar el uso de embeddingElm.contentDocument
(si está disponible) en lugar de embeddingElm.getSVGDocument()
.
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 desencadena en el punto en que el agente de usuario ha analizado por completo el elemento y sus descendientes y está listo para actuar de manera apropiada sobre ese elemento
Puede intentar sondear de vez en cuando.
function checkReady() {
var svg = document.getElementById("chart").getSVGDocument();
if (svg == null) {
setTimeout("checkReady()", 300);
} else {
...
}
}
Suponiendo que su SVG está en una etiqueta <embed>
:
<embed id="embedded-image" src="image.svg" type="image/svg+xml" />
La imagen SVG se encuentra esencialmente en un subdocumento que tendrá un evento de load
separado del del document
principal. Sin embargo, puedes escuchar 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, ya que cualquier modificación que realice en el SVG tendrá lugar antes de que se pintee por primera vez, lo que reducirá el parpadeo y el esfuerzo de CPU dedicado a la pintura.
Usando jQuery puedes enlazar al evento de carga de ventana con el que Erik menciona:
$(window).load(function(){
var svg = document.getElementById("chart").getSVGDocument();
});