Warnung
Da ich im Moment diese Seite leider nicht mehr aktiv pflegen und auf dem neuesten Stand halten kann, können manche Informationen bereits veraltet sein. Sollten Änderungen von euch bei mir eintreffen, bin ich jedoch gerne bereit diese hier einzupflegen. Auch Leute, die sich um die Seite bzw. deren Inhalt kümmern möchten, sind gerne gesehen.
 Inhaltsverzeichnis  Interaktivität  Skripte definieren

10.2Skripte definieren

JavaScript-Code kann entweder direkt in das SVG-Dokument, in eine separate .js-Datei oder z.B. auch in eine (X)HTML-Datei, in der sich eine SVG-Grafik befindet oder in der eine selbige referenziert wird, geschrieben werden.

zum Anfang der Seitezum Ende der Seite

10.2.1Direkte Einbindung

 Listing 10-2 zeigt zuerst die direkte Einbindung in eine SVG-Grafik. Diese SVG-Datei beschreibt einen roten Kreis, der seinen Radius verändert, sobald er mit der Maus angeklickt wird.

 Anzeigebeispiel

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
  <script type="text/ecmascript">
  <![CDATA[
    function aendereRadius(evt)
    {
      var kreis = evt.target;
      var radius = kreis.getAttributeNS(null, 'r');

      if(radius < 75)
      {
        kreis.setAttributeNS(null, 'r', parseInt(radius) + 5);
      }
      else
      {
        kreis.setAttributeNS(null, 'r', 25);
      }
    }
  ]]>
  </script>

  <circle cx="75" cy="75" r="25" fill="#F00" onclick="aendereRadius(evt)" />
</svg>
Listing 10-2: Eine SVG-Grafik inkl. JavaScript-Abschnitt

Ein Skriptbereich wird immer durch das <script>-Element eingeleitet. Damit der Betrachter weiß, welche Skriptsprache er für diesen Bereich verwenden soll, bekommt das Attribut type den MIME-Type der gewünschten Sprache zugewiesen. Die SVG 1.1-Spezifikation definiert als Standardwert den Typ text/ecmascript (der SVG 1.2-Entwurf derzeit application/ecmascript), der wohl auch am häufigstens benutzt wird. Möchte man im gesamten Dokument von vornherein nur eine einzige Sprache verwenden, kann man im <svg>-Element auch das contentScriptType-Attribut mit dem entsprechenden MIME-Type versehen.

Nach dem einleitenden <script>-Tag folgt die Umklammerung des JavaScript-Codes durch <![CDATA[ und ]]>. Liegt ein Bereich innerhalb eines solchen CDATA-Blocks (CDATA steht für "character data"), wird alles, was sich darin befindet, vom XML-Parser ignoriert. Nur die Zeichenfolge ]]>, die das Ende des CDATA-Blocks bekannt gibt, wird von ihm interpretiert. In solche Blöcke läßt sich z.B. SVG-Code schreiben, der als Kommentar dienen soll. Im vorherigen Beispiel ist der CDATA-Bereich zwingen notwendig, weil in der if-Bedingung das Zeichen < vorkommt, das dem Parser den Anfang eines Tags anzeigt. Verzichtet man in diesem Fall also auf den CDATA-Block, wird die Validierung des SVG-Dokuments fehlschlagen. Um Schwierigkeiten schon im voraus zu vermeiden, sollte man sich unbedingt angewöhnen, Skript-Code grundsätzlich in einen CDATA-Block zu schreiben.

zum Anfang der Seitezum Ende der Seite

10.2.2Einbindung in eine separate Skript-Datei

Die folgende Methode zeigt, wie JavaScript-Code in eine separate JavaScript-Datei ausgelagert werden kann. Um SVG-Beschreibung und Programm-Code aus  Listing 10-2 zu trennen, genügt es die Funktion aendereRadius() aus dem CDATA-Block zu entfernen und in eine neue Datei zu transferieren, welche man anschließend mit der Endung .js abspeichert. Der nun leere, übriggebliebene Skript-Abschnitt wird durch ein <script>-Element ersetzt, das den MIME-Type der verwendeten Sprache und einen Link auf die neu erstellte JavaScript-Datei enthält. Während  Listing 10-3 die um den Skript-Code reduzierte SVG-Grafik beinhaltet, stellt  Listing 10-4 die neue Datei mit der umgezogenen JavaScript-Funktion dar.

 Anzeigebeispiel

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg version="1.1"
     xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink">
  <script type="text/ecmascript" xlink:href="script3_example.js" />

  <circle cx="75" cy="75" r="25" fill="#F00" onclick="aendereRadius(evt)" />
</svg>
Listing 10-3: Die SVG-Datei mit einem Link auf eine externe .js-Datei
function aendereRadius(evt)
{
  var kreis = evt.target;
  var radius = kreis.getAttributeNS(null, 'r');
  if(radius < 75)
  {
    kreis.setAttributeNS(null, 'r', parseInt(radius) + 5);
  }
  else
  {
    kreis.setAttributeNS(null, 'r', 25);
  }
}
Listing 10-4: Der von dem SVG-Dokument referenzierte JavaScript-Code
zum Anfang der Seitezum Ende der Seite

10.2.3Einbindung in eine HTML-Datei

Um die SVG-Grafik mit Hilfe eines externen Skripts steuern zu können, muß das obige Beispiel leicht abgeändert werden. Um Zugriff auf das <circle>-Objekt zu erhalten, wird dieses nun mit der ID kreis ausgestattet. Mittels document.getElementById("kreis") kann somit der Variablen kreis eine Referenz auf das Objekt übergeben werden (siehe  Listing 10-5).

 Anzeigebeispiel

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="150" height="150">
  <script type="text/ecmascript">
  <![CDATA[
    function aendereRadius()
    {
      var kreis = document.getElementById("kreis");
      var radius = kreis.getAttributeNS(null, 'r');

      if(radius < 75)
      {
        kreis.setAttributeNS(null, 'r', parseInt(radius) + 5);
      }
      else
      {
        kreis.setAttributeNS(null, 'r', 25);
      }
    }
  ]]>
  </script>

  <circle id="kreis" cx="75" cy="75" r="25" fill="#F00" />
</svg>
Listing 10-5: Die leicht modifizierte SVG-Datei

 Listing 10-6 zeigt die zu diesem Beispiel dazugehörige XHTML-Datei. Darin wird die SVG-Grafik mittels <object>-Element eingebunden. Zusätzlich enthält sie eine Schaltfläche, die bei Aktivierung die Funktion aendereRadius() des SVG-Dokuments aufruft. Damit diese Kopplung von XHTML- und SVG-Dokument funktioniert, befindet sich eine kleine Funktion mit dem Namen init() im Header der XHTML-Datei. Sie ermöglicht den Zugriff auf die beiden Objekte document und window des SVG-Dokuments.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
  "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de">
  <head>
    <title>SVG Scripting - Variante 2a</title>
    <meta http-equiv="Content-Script-Type" content="text/ecmascript" />
    <script type="text/ecmascript">
    <![CDATA[
      var svgDoc = null;
      var svgWin = null;

      function init()
      {
        var object = document.getElementById('object');
        svgDoc = object.contentDocument;
        svgWin = svgDoc.defaultView;
      }
    ]]>
    </script>
  </head>
  <body onload="init()">
    <div>
      <object id="object" data="script2a_example.svg" type="image/svg+xml"
        width="150" height="150" style="border:1px solid #000000">
      </object>
      <p>
        <button onclick="svgWin.aendereRadius()">Ändere Radius</button>
      </p>
    </div>
  </body>
</html>
Listing 10-6: Die XHTML-Datei mit per <object>-Element eingebetteter SVG-Grafik

Es ist zu beachten, daß es sich bei dieser Zugriffsmethode um die standardkonforme, vom W3C verabschiedete Methode handelt. Leider wurde im Internet Explorer 6 die HTMLObjectElement-Schnittstelle, mit welcher der obige Zugriff auf das <object>-Element realisiert wird, nicht implementiert. Allerdings bietet der SVG-Standard selbst eine Schnittstelle des Namens GetSVGDocument an, mit der man eine Referenz auf das SVG-Dokument erhält. Wegen Sicherheitsproblemen wurde jedoch deren Unterstützung im Adobe SVG Plugin 3.03 entfernt. Aber auch den Mozilla-basierten Browsern mit nativer SVG-Unterstützung fehlt noch eine Implementierung der GetSVGDocument-Schnittstelle für das <object>-Element. Der Zugriff auf das window-Objekt des SVG-Dokuments mit dem Adobe SVG Plugin bereitet ebenfalls Schwierigkeiten. Mit Mozilla-basierten Browsern kann man die vom W3C standardisierte Eigenschaft defaultView des document-Objekts problemlos nutzen, um eine Referenz auf das window-Objekt zu erhalten. Dem Adobe SVG Plugin für den Internet Explorer fehlt jedoch die dafür notwendige DocumentView-Schnittstelle. Und auch die proprietäre Eigenschaft window oder die ebenfalls nicht standardkonforme Methode getWindow() wurden wegen den bereits erwähnten Sicherheitsproblemen entfernt. Somit scheint es derzeit nicht möglich zu sein mit dem Adobe SVG Plugin auf mittels <object>-Element eingebundene SVG-Dokumente zuzugreifen. Eine Alternative wäre die Verwendung des HTML-Elements <embed>, das jedoch als veraltet gilt und in neueren Standards nicht mehr berücksichtig wird.

Selbstverständlich besteht auch die Möglichkeit das komplette Scripting innerhalb des (X)HTML-Dokuments zu notieren. In einem solchen Fall sieht die SVG-Grafik mit dem roten Kreis wie in  Listing 10-7 dargestellt aus.

 Anzeigebeispiel

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="150" height="150">
   <circle id="kreis" cx="75" cy="75" r="25" fill="#F00" />
</svg>
Listing 10-7: SVG-Dokument ohne jeglichen Skript-Bereich

Das leicht veränderte und um die Funktion aendereRadius() erweiterte XHTML-Dokument zeigt  Listing 10-8.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
  "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de">
  <head>
    <title>SVG Scripting - Variante 2b</title>
    <meta http-equiv="Content-Script-Type" content="text/ecmascript" />
    <script type="text/ecmascript">
    <![CDATA[
      var svgDoc = null;
      var svgWin = null;

      function init()
      {
        var object = document.getElementById('object');
        svgDoc = object.contentDocument;
        svgWin = svgDoc.defaultView;
      }

      function aendereRadius()
      {
        var kreis = svgDoc.getElementById("kreis");
        var radius = kreis.getAttributeNS(null, 'r');
        if(radius < 75)
        {
          kreis.setAttributeNS(null, 'r', parseInt(radius) + 5);
        }
        else
        {
          kreis.setAttributeNS(null, 'r', 25);
        }
      }
    ]]>
    </script>
  </head>
  <body onload="init()">
    <div>
      <object id="object" data="script2b_example.svg" type="image/svg+xml"
        width="150" height="150" style="border:1px solid #000000">
      </object>
      <p>
        <button onclick="aendereRadius()">Ändere Radius</button>
      </p>
    </div>
  </body>
</html>
Listing 10-8: Die XHTML-Datei mit dem gesamten Skript-Code
zum Anfang der Seite
zum vorherigen Kapitel  DOM
zum nächsten Kapitel  Inline-Code
 Inhaltsverzeichnis  Interaktivität  Skripte definieren