2010-05-02 3 views
65

Ich bin mit SVG herumspielen und ich hoffte, ich könnte SVG-Dateien in Illustrator erstellen und Elemente mit Javascript zugreifen.Zugriff auf SVG-Elemente mit Javascript

Hier ist die SVG-Datei Illustrator tritt aus (Es scheint auch eine Last von Müll auf den Anfang der Datei hinzufügen, die ich entfernt haben)

<?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> 

Wie Sie wahrscheinlich sehen können, hat jedes Element eine ID, und ich hatte gehofft, mit Javascript auf einzelne Elemente zugreifen zu können, damit ich das Füllattribut ändern und auf Ereignisse wie Klick reagieren konnte.

Die HTML ist Moor Grund

<!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> 

Ich denke, das ist wirklich zwei Fragen ist.

  1. Ist es möglich, es auf diese Weise zu tun, im Gegensatz zu etwas wie Raphael oder jQuery SVG zu verwenden.

  2. Wenn es möglich ist, was ist die Technik?


UPDATE

Im Moment habe ich mit Illustrator griff die SVG-Datei zu erstellen, und ich bin mit Raphaël JS Pfade erstellen und einfaches Kopieren der Punktdaten aus die SVG-Datei und Einfügen in path() Funktion. Das Erstellen komplexer Pfade, wie sie für eine Karte benötigt werden, durch die manuelle Kodierung der Punktdaten ist (meines Wissens) unerschwinglich komplex.

Antwort

82

Ist es möglich, es auf diese Weise zu tun, im Gegensatz zu etwas wie Raphael oder jQuery SVG?

Definitiv.

Wenn es möglich ist, was ist die Technik?

Diese kommentierte Code-Schnipsel funktioniert:

<!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> 

Beachten Sie, dass eine Einschränkung dieser Technik ist, dass es durch die Same Origin Policy beschränkt ist, so alpha.svg müssen auf der gleichen Domäne wie der .html gehostet werden Datei, andernfalls ist das innere DOM des Objekts nicht zugänglich.

+3

ein Hinweis auf @ Jbeard4 's Hinweis: in einigen Browsern diese Richtlinie gleichen Ursprungs führt zu der Notwendigkeit, einen Server zu verwenden (auch wenn Sie nur HTML und js [serverside] verwenden) die Zugriffsrichtlinie wird den Zugriff zu verhindern die svg. – Michael

16

Im Fall, dass Sie jQuery benötigen Sie für $(window).load warten, weil das eingebettete SVG-Dokument möglicherweise noch nicht bei $(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); 
}); 
+3

Während der Verwendung dieses Codes, könnte diese andere Antwort eine nützliche Ergänzung sein: http://StackOverflow.com/A/5990945/1515819 –

+0

Dieser Onload-Leckerbissen rettete mein Leben. Vielen Dank – Russ

+0

im Falle von jQuery verwenden Sie besser '$ ('# alphasvg'). Load' statt' $ (window) .load'. Dadurch können Sie das Attribut "Daten" im laufenden Betrieb ändern – vkabachenko

1

geladen wird Wenn Sie einen <img> Tag für den SVG verwenden, dann können Sie nicht manipulieren sein Inhalt (soweit ich weiß).

Wie die akzeptierte Antwort zeigt, ist die Verwendung von <object> eine Option.

brauchte ich diese vor kurzem und verwenden gulp-inject während meines schluck build den Inhalt einer SVG-Datei direkt in das HTML-Dokument als <svg> Element zu injizieren, die dann sehr einfach mit der Verwendung von CSS-Selektoren zu arbeiten und querySelector/getElementBy*.