mr_sol: SVG Objekte mit js ansprechen

Hallo!

Hat von euch jemand eine Idee

Ich möchte per js die Attribute eines SVG Objecte (Instanz) verändern.

Per instanceRoot.correspondingElement klappts in Opera, Chrome und IE 9.
Firefox/Mozilla gar nicht (wird nicht unterstützt)

<?xml version="1.0" encoding="UTF-8"?>  
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:xlink="http://www.w3.org/1999/xlink">  
<head>  
<title>SVG use test</title>  
<script type="text/javascript">  
function setUsedFill(uId, fill) {  
  document.getElementById(uId).instanceRoot.correspondingElement.setAttributeNS(null, 'fill', fill);  
}  
</script>  
</head>  
<body>  
<div>  
<input type="button" value="test"  
       onclick="setUsedFill('uc1', 'yellow');"/>  
</div>  
<div>  
<svg xmlns="http://www.w3.org/2000/svg" width="300" height="300">  
  <defs>  
    <circle id="c1" cx="50" cy="50" r="30" fill="green"/>  
  </defs>  
  <use id="uc1" x="0" y="0" xlink:href="#c1"></use>  
</svg>  
</div>  
</body>  
</html>

Welche Möglichkeit habe ich noch?

Danke in Voraus.

  1. Hallo mr_sol,

    Welche Möglichkeit habe ich noch?

    Unter Firefox 6.02 funktioniert es so:

    <script type="text/javascript">  
    function setUsedFill(uId, fill) {  
      var xlinkns = "http://www.w3.org/1999/xlink";  
      document.getElementById(document.getElementById(uId).getAttributeNS(xlinkns, "href").substring(1)).setAttributeNS(null, "fill", fill);  
    }  
    </script>
    

    Grüße,
    Thomas

    1. Hallo Thomas!

      Klappt leider nicht ganz.
      Ich habe den Code überarbeitet mit zwei Instanzen ausgestattet. Leider klappt es nur mit dem Object.

      Hast du vielleich noch eine Idee.

      <?xml version="1.0" encoding="UTF-8"?>  
      <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:xlink="http://www.w3.org/1999/xlink">  
      <head>  
      <title>SVG use test</title>  
      <script type="text/javascript">  
      function setUsedFill1(uId, fill) {  
        var xlinkns = "http://www.w3.org/1999/xlink";  
        var a = document.getElementById(uId).getAttributeNS(xlinkns, "href").substring(1);  
        document.getElementById(a).setAttributeNS(null, "fill", fill);  
      }  
        
      </script>  
      </head>  
      <body>  
      <div>  
      <input type="button" value="test" onclick="setUsedFill1('uc1', 'yellow');"/>  
      <input type="button" value="test" onclick="setUsedFill1('uc2', 'red');"/>  
      </div>  
      <div>  
      <svg xmlns="http://www.w3.org/2000/svg" width="300" height="300">  
        <defs>  
          <circle id="c1" cx="50" cy="50" r="30" fill="green"/>  
        </defs>  
        <use id="uc1" x="0" y="0" xlink:href="#c1"></use>  
        <use id="uc2" x="100" y="100" xlink:href="#c1"></use>  
      </svg>  
      </div>  
      </body>  
      </html>
      
      1. Hallo mr_sol,

        Klappt leider nicht ganz.
        Ich habe den Code überarbeitet mit zwei Instanzen ausgestattet. Leider klappt es nur mit dem Object.

        Hat bei mir im Firfox exakt wie beschrieben funktioniert (Buttonklick --> grüner Kreis wird gelb).

        Hast du vielleich noch eine Idee.

        Im Moment nicht.

        Grüße,
        Thomas

        1. Hallo Thomas!

          Hier sieht man das Problem besser. Es gibt 2 Instanzen von c1. (uc1,uc2) ich möchte unabhängig bei beiden die Farbe verändern.

            
          <?xml version="1.0" encoding="UTF-8"?>  
          <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:xlink="http://www.w3.org/1999/xlink">  
          <head>  
          <title>SVG use test</title>  
          <script type="text/javascript">  
          function setUsedFill(uId, fill) {  
            document.getElementById(uId).instanceRoot.correspondingElement.setAttributeNS(null, 'fill', fill);  
          }  
          </script>  
          </head>  
          <body>  
          <div>  
          <input type="button" value="test" onclick="setUsedFill('uc1', 'yellow');"/>  
          <input type="button" value="test" onclick="setUsedFill('uc2', 'red');"/>  
          </div>  
          <div>  
          <svg xmlns="http://www.w3.org/2000/svg" width="300" height="300">  
            <defs>  
              <circle id="c1" cx="50" cy="50" r="30" fill="green"/>  
            </defs>  
            <use id="uc1" x="0" y="0" xlink:href="#c1"></use>  
            <use id="uc2" x="100" y="100" xlink:href="#c1"></use>  
          </svg>  
          </div>  
          </body>  
          </html>  
          
          
          1. Hallo mr_sol,

            Hier sieht man das Problem besser. Es gibt 2 Instanzen von c1. (uc1,uc2) ich möchte unabhängig bei beiden die Farbe verändern.

            Alternativer Vorschlag über verschiedene Symbole und Austausch der use-Referenzen statt der Farben selbst:

            <?xml version="1.0" encoding="UTF-8"?>  
            <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:xlink="http://www.w3.org/1999/xlink">  
            <head>  
            <title>SVG use test</title>  
            <script type="text/javascript">  
              
             [code lang=javascript] var xlinkns = "http://www.w3.org/1999/xlink";  
              var f_vs_id = {'green' : '#c1', 'yellow' : '#c2', 'red' : '#c3'};  
              
              function setUsedFill(uId, fill) {  
                document.getElementById(uId).setAttributeNS(xlinkns, 'href', f_vs_id[fill]);  
              }
            

            </script>
            </head>
            <body>
            <div>
            <input type="button" value="test" onclick="setUsedFill('uc1', 'yellow');"/>
            <input type="button" value="test" onclick="setUsedFill('uc2', 'red');"/>
            </div>
            <div>
            <svg xmlns="http://www.w3.org/2000/svg" width="300" height="300">
              <defs>
                <symbol id="c1">
                  <circle cx="50" cy="50" r="30" fill="green"/>
                </symbol>
                <symbol id="c2">
                  <circle cx="50" cy="50" r="30" fill="yellow"/>
                </symbol>
                <symbol id="c3">
                  <circle cx="50" cy="50" r="30" fill="red"/>
                </symbol>
              </defs>
              <use id="uc1" x="0" y="0" xlink:href="#c1"></use>
              <use id="uc2" x="100" y="100" xlink:href="#c1"></use>
            </svg>
            </div>
            </body>
            </html>[/code]

            Grüße,
            Thomas

            1. Hallo Thomas!

              Danke für deine Unterstützung

              ;-) Raffiniert - Austausch der use-Referenz.

              Die Sache dürfte wirklich vertrackt sein. Alternativ wäre noch
              svg:oject per param ansprechen - hier gibt das Problem das sich diese
              nicht innerhalb der svg Tags befinden dürfen.

              Klappt nicht:

                
              <!DOCTYPE html>  
              <html xmlns="http://www.w3.org/1999/xhtml">  
              <head>  
                 <title>Test</title>  
              </head>  
              <body>  
              <svg width="2000" height="2000">  
                     <object type="image/svg+xml" data="lamp.svg" style="width: 450px; height:150px;">  
                        <param name="color" value="yellow" />  
                     </object>  
              </svg>  
              </body>  
              </html>  
              
              
                
              <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="40" height="40">  
              <title>lamp</title>  
                <circle cx="30" cy="30" r="15" fill="param(color)" stroke-width=""/>  
              </svg>  
              
              

              Weiter Alternative mit:

                
              <image x="0" y="0" width="20" height="20" xlink:href="lamp.svg"><param name="color" value="yellow" /></image>  
              
              

              hier ist param nicht erlaubt