Comment accéder aux éléments SVG avec Javascript

Je m'amuse avec SVG et j'espérais pouvoir créer des fichiers SVG dans Illustrator et accéder aux éléments avec Javascript.

Voici L'illustrateur SVG file kicks out (il semble aussi ajouter un tas de ferraille au début du fichier que j'ai supprimé)

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     width="276.843px" height="233.242px" viewBox="0 0 276.843 233.242" enable-background="new 0 0 276.843 233.242"
     xml:space="preserve">
<path id="delta" fill="#231F20" d="M34.074,86.094L0,185.354l44.444,38.519l80.741-0.74l29.63-25.186l-26.667-37.037
    c0,0-34.815-5.926-37.778-6.667s-13.333-28.889-13.333-28.889l7.407-18.519l31.111-2.963l5.926-21.481l-12.593-38.519l-43.704-5.185
    L34.074,86.094z"/>
<path id="cargo" fill="#DFB800" d="M68.148,32.761l43.704,4.445l14.815,42.963l-7.407,26.667l-33.333,2.963l-4.444,14.074
    l54.074-1.481l22.222,36.296l25.926-3.704l25.926-54.074c0,0-19.259-47.408-21.481-47.408s-31.852-0.741-31.852-0.741
    l-19.259-39.259L92.593,8.316L68.148,32.761z"/>
<polygon id="beta" fill="#35FF1F" points="86.722,128.316 134.593,124.613 158.296,163.872 190.889,155.724 214.593,100.909 
    194.593,52.02 227.186,49.057 246.444,92.02 238.297,140.909 216.074,172.761 197.556,188.316 179.778,169.798 164.963,174.983 
    163.481,197.946 156.815,197.946 134.593,159.428 94.593,151.279 "/>
<path class="monkey" id="alpha" fill="#FD00FF" d="M96.315,4.354l42.963,5.185l18.519,42.222l71.852-8.148l20.74,46.667l-5.926,52.593
    l-24.444,34.074l-25.185,15.555l-14.074-19.259l-8.889,2.964l-1.481,22.222l-14.074,2.963l-25.186,22.963l-74.074,4.444
    l101.481,4.444c0,0,96.297-17.777,109.63-71.852S282.24,53.983,250.389,20.65S96.315,4.354,96.315,4.354z"/>
</svg>

comme vous pouvez probablement le voir, chaque élément a un ID, et j'espérais pouvoir accéder à des éléments individuels avec Javascript pour que je puisse changer l'attribut Fill et répondre à des événements tels que le clic.

Le HTML est de la tourbière de base

<!DOCTYPE html>
<html>
    <head>
        <title>SVG Illustrator Test</title> 
    </head>
    <body>

        <object data="alpha.svg" type="image/svg+xml" id="alphasvg" width="100%" height="100%"></object>

    </body>
</html>

je suppose que c'est vraiment deux questions.

  1. est-il possible de le faire de cette façon, par opposition à utiliser quelque chose comme Raphael ou jQuery SVG.

  2. si c'est possible, quelle est la technique?


mise à JOUR

pour le moment, J'ai eu recours à Illustrator pour créer le fichier SVG, et j'utilise Raphaël JS pour créer des chemins et simplement copier les données de points du fichier SVG et les coller dans la fonction path() . Créer des chemins complexes comme ceux qui pourraient être nécessaires pour une carte, en codant les données de points manuellement est (à ma connaissance) extrêmement complexe.

71
demandé sur lambda 2010-05-02 18:17:47

3 réponses

est-il possible de le faire de cette façon, plutôt que D'utiliser quelque chose comme Raphaël ou jQuery SVG?

définitivement.

Si c'est possible, quelle est la technique?

ce code annoté "snippet works:

<!DOCTYPE html>
<html>
    <head>
        <title>SVG Illustrator Test</title> 
    </head>
    <body>

        <object data="alpha.svg" type="image/svg+xml"
         id="alphasvg" width="100%" height="100%"></object>

        <script>
            var a = document.getElementById("alphasvg");

            // It's important to add an load event listener to the object,
            // as it will load the svg doc asynchronously
            a.addEventListener("load",function(){

                // get the inner DOM of alpha.svg
                var svgDoc = a.contentDocument;
                // get the inner element by id
                var delta = svgDoc.getElementById("delta");
                // add behaviour
                delta.addEventListener("mousedown",function(){
                        alert('hello world!')
                }, false);
            }, false);
        </script>
    </body>
</html>

noter que l'une des limites de cette technique est qu'elle est restreinte par la Politique de même origine, de sorte que alpha.svg doit être hébergé sur le même domaine que le fichier .html , sinon le DOM intérieur de l'objet sera inaccessible.

91
répondu jbeard4 2016-08-04 15:09:32

dans le cas où vous utilisez jQuery vous devez attendre $(window).load , parce que le document SVG intégré pourrait ne pas être encore chargé à $(document).ready

$(window).load(function () {

    //alert("Document loaded, including graphics and embedded documents (like SVG)");
    var a = document.getElementById("alphasvg");

    //get the inner DOM of alpha.svg
    var svgDoc = a.contentDocument;

    //get the inner element by id
    var delta = svgDoc.getElementById("delta");
    delta.addEventListener("mousedown", function(){ alert('hello world!')}, false);
});
17
répondu jediz 2016-08-04 17:19:24

si vous utilisez une étiquette <img> pour la SVG, vous ne pouvez pas manipuler son contenu (autant que je sache).

comme le montre la réponse acceptée, l'utilisation de <object> est une option.

j'en avais besoin récemment et j'ai utilisé gulp-inject lors de ma construction gulfp pour injecter le contenu d'un fichier SVG directement dans le document HTML comme un élément <svg> , qui est alors très facile à travailler avec l'utilisation de sélecteurs CSS et querySelector / getElementBy* .

2
répondu Drew Noakes 2017-10-01 20:43:41