web-dev-qa-db-fra.com

Comment vérifier si un document SVG intégré est chargé dans une page html?

J'ai besoin de modifier (en utilisant javascript) un document SVG intégré dans une page html.

Lorsque le SVG est chargé, je peux accéder au dom du SVG et de ses éléments. Mais je ne suis pas en mesure de savoir si le dom SVG est prêt ou non, donc je ne peux pas effectuer d'actions par défaut sur le SVG lorsque la page html est chargée.

Pour accéder au dom SVG, j'utilise ce code:

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

où "graphique" est l'id de l'élément incorporé.

Si j'essaie d'accéder au SVG lorsque le document html est prêt, de cette façon:

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

svg est toujours nul. J'ai juste besoin de savoir quand ce n'est pas nul, donc je peux commencer à le manipuler. Savez-vous s'il existe un moyen de le faire?

36
alexmeia

Sur votre élément d'intégration (par exemple 'embed', 'object', 'iframe') dans le document principal, ajoutez un attribut onload qui appelle votre fonction, ou ajoutez l'écouteur d'événement dans le script, par exemple embeddingElm.addEventListener('load', callbackFunction, false). Une autre option pourrait être d'écouter DOMContentLoaded, dépend de ce que vous voulez.

Vous pouvez également ajouter un écouteur de chargement sur le document principal. jQuery(document).ready ne signifie pas que toutes les ressources sont chargées, juste que le document lui-même a un DOM prêt à l'action. Cependant, notez que si vous écoutez la charge sur tout le document, votre fonction de rappel ne sera pas appelée tant que toutes les ressources de ce document ne seront pas chargées, css, javascript, etc.

Si vous utilisez svg en ligne, alors jQuery(document).ready fonctionnera très bien cependant.

Sur une autre note, vous voudrez peut-être envisager d'utiliser embeddingElm.contentDocument (Si disponible) au lieu de embeddingElm.getSVGDocument().

22
Erik Dahlström

Vous pouvez utiliser un événement onload pour la vérification.

Supposons que some.svg soit incorporé dans la balise object:

<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");
}
12
Roshan Poudyal

En supposant que votre SVG est dans un <embed> tag:

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

L'image SVG est essentiellement dans un sous-document qui aura un événement load distinct de celui du document principal. Cependant, vous pouvez écouter cet événement et le gérer:

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

C'est mieux que d'interroger, car toute modification apportée au SVG se produira avant sa première peinture, ce qui réduira le scintillement et les efforts du processeur consacrés à la peinture.

8
Drew Noakes

L'événement de chargement de l'élément d'intégration (par exemple, un objet) serait ma préférence mais, si ce n'est pas une solution viable pour une raison quelconque, le seul test générique et fiable que j'ai trouvé pour SVG DOM prêt est la méthode getCurrentTime du SVG élément racine:

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 */
}

recommandation W3C SVG indique que getCurrentTime sur un SVGSVGElement:

Renvoie l'heure actuelle en secondes par rapport à l'heure de début du fragment de document SVG actuel. Si getCurrentTime est appelé avant le début de la chronologie du document (par exemple, en exécutant un script dans un élément "script" avant l'envoi de l'événement SVGLoad du document), 0 est renvoyé.

3
Terence Bandoian

En utilisant jQuery, vous pouvez vous lier à l'événement de chargement de fenêtre mentionné par Erik avec:

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

Pour référence future: une solution Angular (8)/ TypeScript ressemble à ceci:

  @ViewChild('startimage', {static:false})
  private startimage: ElementRef;
...
  this.startimage.nativeElement.addEventListener('load', () => {
    alert('loaded');
  });

Vous pouvez accéder au svg par const svg = this.startimage.nativeElement.getSVGDocument();

0
LosManos