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.
-
est-il possible de le faire de cette façon, par opposition à utiliser quelque chose comme Raphael ou jQuery SVG.
-
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.
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.
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);
});
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*
.