Frank123: Zugiff auf SVG-JS-Variablen

Hallo Leute,

erstmal die beiden Dateien um die es geht:

test.html:

  
<html>  
<head>  
<title>Hallo</title>  
<script language="Javascript">  
function setHook()  
{  
	test_svg.clickHook = myHook;  
}  
function myHook(x, y)  
{  
	alert('myHook (' + x + '/' + y + ')');  
}  
</script>  
</head>  
<body>  
<object name="test_svg" data="test.svg" type="image/svg+xml">  
	<param name="src" value="test.svg">  
</object>  
<button onclick="setHook();"><div>setHook</div></button>  
</body>  
</html>  

test.svg:

  
<?xml version="1.0" encoding="iso-8859-1"?>  
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"  
 "http://www.w3.org/TR/2001/  
  REC-SVG-20010904/DTD/svg10.dtd">  
<svg width="310" height="140"  
 xmlns="http://www.w3.org/2000/svg"  
 xmlns:xlink="http://www.w3.org/1999/xlink">  
<script language="Javascript"><![CDATA[  
	function test(x, y)  
	{  
		alert('x: ' + x + ' y: ' + y);  
	}  
	var clickHook = test;  
]]></script>  
 <g style="stroke:black;fill:black"  
	transform="translate(30,30)">  
   <rect name="sven" id="mark" x="0" y="0" width="10" height="10" onclick="clickHook(1,1);" />  
   <rect x="20" y="20" width="10" height="10" onclick="clickHook(2,2);" />  
   <rect x="40" y="40" width="10" height="10" onclick="clickHook(4,4);" />  
 </g>  
</svg>  

System:
Windows XP 32 Bit SP3, XAMPP 1.7.2
IE 8.0.60001.18702 (SVGView 3.02 Build 94), FF 3.5.1 + FireBug 1.4.3
Ausführort: localhost

Problembeschreibung:
Ich möchte das JavaScript-Code im Host-Dokument ausgeführt wird, wenn auf ein Element im Object-Tag (also dem SVG) geklickt wird.
Im Firefox funktioniert dieses Beispiel problemlos. Nach dem Klick auf den Button setHook wird die Variable clickHook im SVG korrekt gesetzt und jetzt durch einen Klick auf eins der Elemente ausgelöst.
In einer zweiten Variante habe ich das document-Object eingefügt. Dadurch wurde [b]test_svg.clickHook[/b] zu [b]test_svg.document.clickHook[/b]. Auch diese Variante funktioniert im Firefox.
Im Internet-Explorer ist davon leider nichts zu erkennen. Ich kann zwar in beiden Fällen die Variable erfolgreich setzen und sogar mittels des integrierten Entwicklertool wieder auslesen. Diese ist auch in beiden Fällen korrekt gesetzt, doch bei einem Klick auf eins der Elemente wird nicht die myHook ausgeführt, sondern die test Funktion.
Probiert habe ich mittels console.log (im FF+Firebug wie auch im Entwicklertool des IE8 verfügbar) mittels getElementById und getElementsByName auf einzelne Elemente zuzugreifen und den onclick-Handler von Hand einmal zusetzen. Das Entwicklertool sagt mir zwar das der Handler korrekt gesetzt wurde, aber es wird immer noch die falsche Funktion ausgelöst.
Gibt es eine Möglichkeit auf die Variablen im SVG bei dem Internet Explorer zuzugreifen?
Auf Abwärtskompatibilität (ff3 o. IE7) und andere Browser (Netscape und co.) kann ich verzichten.

Danke für jede Hilfe

Frank

  1. Hej Frank,

    da der IE den SVG Standard nicht unterstützt, und daher ein Plugin zum Anzeigen von SVG verwendet werden muss, vermute ich, es liegt an diesem Plugin.
    Der IE "ignoriert" ja beim parsen den object-Knoten und delegiert den Inhalt an das dementsprechende Plugin (sofern vorhanden). SVGView wird nun nichts vom JavaScript in der Host-Webseite wissen, was dazuführt die Variable 'clickHood' eine Referenz auf die Funktion 'test' hält und nicht durch die Funktion 'setHood' in der Host-Webseite überschrieben werden kann.

    Ein Lösungsansatz wäre SVG direkt in die test.html einzubetten, oder ein Toolkit zu verwenden dass dir einen Abstraktionslayer bietet.
    Mittels SVGWeb wird SVG in unterstützenden Browsern nativ dargestellt; im IE wird dazu Flash verwendet.

    Liebe Grüße
    Dave

    1. Danke für die Antwort.
      Ich werde das gleich mal ausprobieren. Die direkte Einbettung fällt leider für mich flach, da es sich um Kartendaten (nicht im Sinne von geographischen Karten) handelt, die zum Teil 2 mb (SVG-Quellcode) übersteigen können und somit hoffentlich Platz im Cache finden.

      Gruß

      Frank

      1. Hab mir die Leistungsfähigkeit von SVG mal angeguckt und muss leider sagen das ich doch son bischen enttäuscht bin. Werde mich doch wohl wieder auf PNG's mit riesen Javascipt-Array stürzen müssen.
        Aber nochmal danke für den Tipp ich finde die Flash-Varianteum einiges schöner wie den Adobe SVGView.

        Gruß

        Frank

        1. Hej Frank,

          Hab mir die Leistungsfähigkeit von SVG mal angeguckt und muss leider sagen das ich doch son bischen enttäuscht bin.

          Bei SVG Dateien mit einer Größe von 2MB ist klar, dass das Rendering eine Zeit dauert...
          Hierbei sei auch noch anzumerken, dass Firefox nicht unbedingt der schnellste beim Darstellen von SVG ist. Da ich an einem ähnlichen Projekt arbeite, hab ich mir die Performance der unterschiedlichen Browser genauer angesehen.

          Folgendes Beispiel erzeugt 360 Kreise, mit einem Durchmesser von 10px, in einem Muster.

            
            
          //die Circle-Klasse erzeugt ein svg:circle bzw. vml:oval DOM Element  
          //canvas repräsentiert die Zeichenfläche (in SVG: svg-Element, in VML: group-Element)  
          //'canvas.add' fügt den erzeugten DOM Knoten mittels 'appendChild' in die Zeichenfläche ein.  
          function circlePattern(){  
             var radius = 15;  
             var centerX, centerY = 400;  
             for(var i=0; i<360; i++){  
                 canvas.add( new Circle(  
                    centerX + (Math.sin( i ) * radius),  
                    centerY + (Math.cos( i ) * radius),  
                    10  
                 );  
                 radius += 0.5;  
             }  
            
          }  
          
          

          Das Ergebnis:
          Firefox 3.5: 800ms
          Chrome & Safari: 2ms !
          IE (rendert VML Elemente): 21000ms !
          IE (rendert in Flash): 21ms

          Beim IE ist mir aufgefallen, dass das Einfügen der erzeugten VML Elemente in den DOM das Bottleneck darstellt. Ist jedoch der VML-Code in der Webseite eigebettet, so rendert er diesen schneller als Firefox SVG.

          Aber nochmal danke für den Tipp ich finde die Flash-Varianteum einiges schöner wie den Adobe SVGView.

          Wie oben beschrieben ist die Darstellung von SVG in Chrome und Safari sehr schnell. Sollte es nun egal sein, ob man für dein Projekt ein Plugin benötigt, so würde ich dir Google Chrome Frame empfehlen.
          Dabei brauchst du keinen Umweg über PNG's zu gehen und SVG bleibt scriptable...

          Greetz
          dave

          1. Erstmal danke für die Antworten!
            Ich werde mir die Alternative noch einmal ansehen. Vll gibts ja doch noch Hoffnung ;) sind allerdings 30.000 Punkte. Mal gucken wie FF und co dadrauf reagieren.

            Gruß

            Frank

        2. Hallo Frank,

          Hab mir die Leistungsfähigkeit von SVG mal angeguckt und muss leider sagen das ich doch son bischen enttäuscht bin.

          Leistungsfähigkeit != Browserunterstützung

          Dein Zugriffsproblem lässt sich im IE+ASV so lösen:
          test_svg.window.clickHook = myHook;

          Grüße,
          Thomas