Jens: In SVG-Datei auf Elemente in einer anderen SVG-Datei zugreifen

Hallo, weiß jemand zu folgendem Problem Rat?

Ich habe in einer HTML-Datei zwei SVG-Dateien eingebunden (map.svg, koordinaten.svg). In der map.svg gibt es ein Rechteck mit id=koordinatenbereich.
Ich möchte mir die Maus-Koordinaten vom Rechteck id= koordinatenbereich aus der map.svg in der koordinaten.svg Anzeigen lassen.
Die Funktion wie ich mir die Mauskoordinaten hole ist nicht das
Problem, aber ich schaffe es nicht auf die map.svg zuzugreifen.

Geht das überhaupt aus einer svg-Datei?

Ich hoffe mir kann jemand helfen?

  1. Hallo,

    Geht das überhaupt aus einer svg-Datei?

    Dazu mal ein Beispiel mit je einem (roten) Kreis und einem (gruenen) Rechteck, die in separaten SVG-Dokumenten liegen und ueber embed bzw. iframe eingebunden werden (object waere zwar noch besser, damit klappt das Folgende aber maximal lokal und nicht via http, siehe: http://svglbc.datenverdrahten.de/embed_object_iframe.htm).

    Beim Anklicken der roten Kreises wird die x-Koordinate der daneben angeordneten Rechtecke ausgelesen (Ergebnis: x=20).

    test.htm:

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    <head>
    <title>Test by TM 03/04</title>
    </head>
    <body>
    embed<br>
    <embed name="test1" src="kreis1.svg" width="100" height="100" type="image/svg+xml">
    <embed name="test2" src="rechteck.svg" width="800" height="100" type="image/svg+xml">
    <br>
    iframe<br>
    <iframe name="test3" src="kreis2.svg" width="100" height="100" frameborder="0"></iframe>
    <iframe name="test4" src="rechteck.svg" width="800" height="100" frameborder="0"></iframe>
    </body>
    </html>

    kreis1.svg (fuer den embed-Test):

    <?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
    <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
      "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">

    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

    <circle cx="40" cy="30" r="20" style="fill: #F00" onclick="alert('x='+top.window.document.embeds['test2'].getSVGDocument().getElementById('rechteck').getAttribute('x'))"/>
      <text x="15" y="65">Klick mich!</text>

    </svg>

    kreis2.svg (fuer den object-Test):

    <?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
    <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
      "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">

    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

    <circle cx="40" cy="30" r="20" style="fill: #F00" onclick="alert('x='+window.top.frames.item('test4').document.embeds[0].getSVGDocument().getElementById('rechteck').getAttribute('x'))"/>
      <text x="15" y="65">Klick mich!</text>

    </svg>

    rechteck.svg (fuer beide Tests):

    <?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
    <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
      "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">

    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

    <rect id="rechteck" x="20" y="10" width="40" height="40" style="fill: #090"/>

    </svg>

    Das Ganze (speziell der Zugriff ueber top.window) ist zurzeit leider auf die Kombination IE+ASV beschraenkt.

    MfG, Thomas

    --
    SVG - Learning By Coding
    http://svglbc.datenverdrahten.de/
    1. Hallo Thomas,

      vielen Dank für Deine Tipps, haben funktioniert.

      Ist es auch möglich z.B. mit Klick auf den roten Kreis
      eine Funktion aufzurufen, die dann für das blaue Rechteck
      wirksam wird. Zum Beispiel eine Funktion die auf Klick das
      blaue Rechteck (oder mehrere Objekte) zoomen läßt, oder Ähnliches?

      Danke für Deine Hilfe!

      mfg Jens

      1. Hallo,

        Ist es auch möglich z.B. mit Klick auf den roten Kreis
        eine Funktion aufzurufen, die dann für das blaue Rechteck
        wirksam wird. Zum Beispiel eine Funktion die auf Klick das
        blaue Rechteck (oder mehrere Objekte) zoomen läßt, oder Ähnliches?

        Verwende statt getAttribute('...') einfach setAttribute('transform','scale(2)'). Mehrere Objekte lassen sich mittels g-Element gruppieren und die Gruppe kann man ebenfalls ueber eine ID steuern.

        Eine im SVG-Dokument mit dem Rechteck definierte Funktion kann man ueber object.window.funktionsname() ansprechen, wobei "object" den Teil vor "getSVGDocument()..." darstellt.

        MfG, Thomas

        --
        SVG - Learning By Coding
        http://svglbc.datenverdrahten.de/
        1. Hallo Thomas,
          Deine beiden Beispiele mit getAttribut und setAttribut konnte ich sehr gut nachvollziehen und funktionieren wie gewünscht. Was ich nicht hinbekomme ist die Echtzeitkkordinaten eines Rechtecks (id=fenster) aus der map.SVG (Name=SVGEmbed) in der SVG-Datei koordinaten.svg (Name=SVG2) anzeigen zu lassen. Mit folgendem Code
          bekomme ich immer die Meldung das kein Objekt gefunden wird:

          koordinaten.svg:

          <?xml version="1.0"?>
          <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
           "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
          <svg width="200" height="100" onmousemove="zeige(evt)">

          <script language="JavaScript" >
           <!--
           function SymError()
           {
              return true;
           }

          window.onerror = SymError;
           //-->
           </script>
           <script type="text/javascript">
                <![CDATA[
             function zeige(evt)
            {
              xm=evt.clientX;
            ym=evt.clientY;
            root=evt.target.top.window.document.embeds['SVGEmbed'].getSVGDocument();
             root.getElementById('fenster').firstChild.setData('Koordinaten: X= '+xm+' Y= '+ym);
            }
                ]]>
           </script>

          <rect id="koordinate2" x="0" y="0" width="200" height="100"
           transform="translate(0 0) translate(101 114) scale(1 1.04202) translate(-101 -114) translate(101 114) scale(1 0.951613)  translate(-101 -114) translate(101 -5) scale(1 0.915254) translate(-101 5) translate(-12 54.5) scale(0.955752 1) translate(12 -54.5) translate(214 54.5) scale(0.958333 1) translate(-214 -54.5)"
           style="fill:none;stroke:none;stroke-width:1"/>

          <text id='koordinate' x='0' y='10' style='font-size:12'>Koordinaten:</text>
          </svg>

          So kann es ja eigentlich nicht funktionieren, da das onmousemove ja eigentlich in der map.svg ausgeführt werden müßte. Aber ich sehe auch
          keinen Ansatz dieses Event zu übergeben. Ich hoffe Du weißt nochmals
          Rat?

          1. Hallo,

            So kann es ja eigentlich nicht funktionieren, da das onmousemove ja eigentlich in der map.svg ausgeführt werden müßte. Aber ich sehe auch
            keinen Ansatz dieses Event zu übergeben.

            Stelle mal alle wichtigen sich gegenseitig aufrufenden Codeteile online, um nicht raten zu muessen ...

            MfG, Thomas

            --
            SVG - Learning By Coding
            http://svglbc.datenverdrahten.de/
            1. Stelle mal alle wichtigen sich gegenseitig aufrufenden Codeteile online, um nicht raten zu muessen ...

              Hallo,
              hab mal alles Online unter: http://www.devilmachine.de/SVG/index.htm
              gestellt. Ich hoffe es gibt eine Lösung!?

              Schon mal lieben Dank!

              mfg Jens

              1. Hallo,

                hab mal alles Online unter: http://www.devilmachine.de/SVG/index.htm
                gestellt. Ich hoffe es gibt eine Lösung!?

                Die Funktion zum Abgreifen der Mauskoordinaten (via onmousemove) muss in das linke Dokument und die Ausgabe erfolgt entsprechend rechts daneben. An den bereits diskutierten Zugriffstechniken aendert sich nichts.

                MfG, Thomas

                --
                SVG - Learning By Coding
                http://svglbc.datenverdrahten.de/
                1. An den bereits diskutierten Zugriffstechniken aendert sich nichts.

                  Hab ich eigentlich auch schon so probiert, aber ich bekam immer die
                  Meldung, daß er kein Objekt gefunden hat. Wahrscheinlich falsche Syntax meiner "Zugriffstechnik" Ich versuche es nochmal,
                  hab vielen Dank.

                  mfg Jens

                  1. Hallo,

                    Hab ich eigentlich auch schon so probiert, aber ich bekam immer die
                    Meldung, daß er kein Objekt gefunden hat. Wahrscheinlich falsche Syntax meiner "Zugriffstechnik"

                    Ich habe es nochmal genauer untersucht. Schreibe in map.svg in den script-Teil:

                    function zeige(evt)
                    {
                      xm=evt.clientX;
                      ym=evt.clientY;
                      root=top.window.document.embeds['SVG2'].getSVGDocument();
                      root.getElementById('koordinate').firstChild.setData('Koordinaten: X= '+xm+' Y= '+ym);
                    }

                    und rufe die Funktion so auf:

                    <svg width="500" height="500" viewBox="0 0 500 500" onmousemove="zeige(evt)">

                    Nimm diese Funktion aus koordinaten.svg heraus. Sinnvoll waere es noch, das Ausgabeobjekt nur ein Mal zu definieren und zwar als globale Variable direkt nach dem Laden (onload).

                    Es waren noch einige kleinere Korrekturen noetig, die ich per Mail sende.

                    MfG, Thomas

                    --
                    SVG - Learning By Coding
                    http://svglbc.datenverdrahten.de/