Manipulating objects with JS

2019-08-09 00:35发布

I want change the attribut off a SVG object.

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

This Code is going on in Opera, Chrome and IE 9.

instanceRoot.correspondingElement - is not running in Firefox/Mozilla

3条回答
狗以群分
2楼-- · 2019-08-09 00:43

In a comment on another answer, you asked "is there any alternative?"

For SVG work, the alternative that I use is the Raphael javascript library.

It is an excellent library for working with SVG grpahics and animations in Javascript; makes things a lot easier, and as an added bonus, it even works in some really old browsers -- including old versions of IE, as far back as IE6.

The reason it works with IE is because it transparently detects the browser and switches to drawing the graphics using VML instead of SVG. But from your perspective as a developer, you don't need to know about this; all you need to know is that it works in all browsers. Sweet.

It also doesn't depend on any other libraries; you don't need to be using JQuery or anything else to use it (although it works just fine with them if you do want to).

I don't do any work at all now in pure SVG; everything is done via Raphael.

查看更多
我只想做你的唯一
3楼-- · 2019-08-09 00:54

Although it's not quite clear in the documentation, setting values in a use element's instanceRoot currentInstance sets the actual element in the def. At least, this is how it appears to work on chrome and IE11. FF29 still has no instanceRoot.

There are two tweaks to get the OP's example to work as intended:

  1. Set the fill of c1 to inherit
  2. In the click handler, set the fill attribute of the use element, not the instanceRoot.correspondingElement.

Here is the OP's code, modified:

<?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) {
          /* Set the fill attribute of the <use> element, not the inner instanceRoot.correspondingElement */  
          document.getElementById(uId).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>
            <!-- set the fill in the def to "inherit" -->
            <circle id="c1" cx="50" cy="50" r="30" fill="inherit"/>
          </defs>
          <use id="uc1" x="0" y="0" xlink:href="#c1" fill="green"></use>
          <use id="uc2" x="100" y="100" xlink:href="#c1" fill="green"></use>
        </svg>
      </div>
    </body>
  </html>
查看更多
迷人小祖宗
4楼-- · 2019-08-09 00:56

From what I can tell here Mozilla doesn't support (or even mention) instanceRoot property.

The page is last updated on June 27, 2011.

AS a side note, in any case - from what I could tell - you require Firefox 4+ to use SVG properly.

EDIT:

Or perhaps, if it suits you, you can change your code a bit:

function setUsedFill1(uId, fill) {
  document.getElementById(uId).setAttributeNS(null, 'fill', fill);
}

and call it:

<input type="button" value="test" onclick="setUsedFill1('c1', 'yellow');"/>

instead.

查看更多
登录 后发表回答