admin管理员组

文章数量:1180520

I'm trying to modify an svg tag with javascript to make it resizable, but my changes have no effect. The reason that I need to do this is that this tag is rendered by a library that I can't modify, and thus it seems like my only choice is to modify the svg with javascript.

I know that the tag that this script produces is correct since I am able to copy the tag to a new html document and it will work (I have included it in the sample code), so it seems like I need some way to force the svg to recognize that it has been changed (or another way to modify the svg).

Here's a HTML page that shows my problem:

<html>
    <head>
        <script src=".min.js"></script>
        <script type="text/javascript">
        $(document).ready(function () {
            var svg = $('#testsvg').find('svg')[0];

            var w = svg.getAttribute('width').replace('px', '');
            var h = svg.getAttribute('height').replace('px', '');

            svg.removeAttribute('width');
            svg.removeAttribute('height');

            svg.setAttribute('viewbox', '0 0 ' + w + ' ' + h);
            svg.setAttribute('preserveaspectratio', 'xminymin meet')

            $(svg)
                .css('width', '100%')
                .css('height', '100%')
                .css('background-color', 'white');
        });
        </script>
    </head>
    <body style="background-color: #333;">
        <div style="width: 80%; height: 40%;">
            <svg id="resultsvg" xmlns="" version="1.1" style="width: 100%; height: 100%; background-color: white; " viewbox="0 0 100 100" preserveaspectratio="xminymin meet">
                <circle cx="50" cy="50" r="40" stroke="black" stroke-width="2" fill="red"></circle>
            </svg>
         </div>
        <div id="testsvg" style="width: 80%; height: 40%;">
            <svg xmlns="" version="1.1" width="100px" height="100px">
                <circle cx="50" cy="50" r="40" stroke="black" stroke-width="2" fill="red" />
            </svg>
        </div>
     </body>
</html>

I'm trying to modify an svg tag with javascript to make it resizable, but my changes have no effect. The reason that I need to do this is that this tag is rendered by a library that I can't modify, and thus it seems like my only choice is to modify the svg with javascript.

I know that the tag that this script produces is correct since I am able to copy the tag to a new html document and it will work (I have included it in the sample code), so it seems like I need some way to force the svg to recognize that it has been changed (or another way to modify the svg).

Here's a HTML page that shows my problem:

<html>
    <head>
        <script src="http://code.jquery.com/jquery.min.js"></script>
        <script type="text/javascript">
        $(document).ready(function () {
            var svg = $('#testsvg').find('svg')[0];

            var w = svg.getAttribute('width').replace('px', '');
            var h = svg.getAttribute('height').replace('px', '');

            svg.removeAttribute('width');
            svg.removeAttribute('height');

            svg.setAttribute('viewbox', '0 0 ' + w + ' ' + h);
            svg.setAttribute('preserveaspectratio', 'xminymin meet')

            $(svg)
                .css('width', '100%')
                .css('height', '100%')
                .css('background-color', 'white');
        });
        </script>
    </head>
    <body style="background-color: #333;">
        <div style="width: 80%; height: 40%;">
            <svg id="resultsvg" xmlns="http://www.w3.org/2000/svg" version="1.1" style="width: 100%; height: 100%; background-color: white; " viewbox="0 0 100 100" preserveaspectratio="xminymin meet">
                <circle cx="50" cy="50" r="40" stroke="black" stroke-width="2" fill="red"></circle>
            </svg>
         </div>
        <div id="testsvg" style="width: 80%; height: 40%;">
            <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100px" height="100px">
                <circle cx="50" cy="50" r="40" stroke="black" stroke-width="2" fill="red" />
            </svg>
        </div>
     </body>
</html>
Share Improve this question asked Jun 11, 2012 at 0:02 NocklasNocklas 1,3675 gold badges15 silver badges29 bronze badges 0
Add a comment  | 

2 Answers 2

Reset to default 25

SVG is case sensitive so

svg.setAttribute('viewbox', '0 0 ' + w + ' ' + h);
svg.setAttribute('preserveaspectratio', 'xminymin meet')

should be written

svg.setAttribute('viewBox', '0 0 ' + w + ' ' + h);
svg.setAttribute('preserveAspectRatio', 'xMinYMin meet')

width and height on the <svg> element are attributes and not styles (unlike html) so you should use setAttribute('width', '100%') rather than .css('width', '100%')

jQuery convert attribute name to lower case; e.g., instead of setting a viewBox attribute, it will set viewbox. Unfortunately, SVG (a XML dialect) element attribute names are case sensitive.

If you wanted to use jQuery consistently, you could use $.attrHooks to handle the case sensitive attributes:

['preserveAspectRatio', 'viewBox'].forEach(function(k) {
  // jQuery converts the attribute name to lowercase before
  // looking for the hook. 
  $.attrHooks[k.toLowerCase()] = {
    set: function(el, value) {
      if (value) {
        el.setAttribute(k, value);
      } else {
        el.removeAttribute(k, value);
      }
      return true;
    },
    get: function(el) {
      return el.getAttribute(k);
    },
  };
});

$(document).ready(function() {
  var svg = $('#testsvg');
  var w = svg.attr('width').replace('px', '');
  var h = svg.attr('height').replace('px', '');

  svg.attr({
    width: '100%',
    height: '100%',
    viewBox: [0, 0, w, h].join(' '),
    preserveAspectRatio: 'xMidYMid meet'
  })
});

Note that el.attr('viewBox', null) would failed; your hook setter won't be called. Instead you should use el.removeAttr('viewBox') or el.attr('viewBox', false).

For other attribute like stroke, I would put them in a stylesheet.

svg {
  background-color: white;
}
circle {
  fill: red;
  stroke: black;
  stroke-width: 1px;
}

If you need to add/toggle class to change the style of a specific elements, you need to use jQuery 1.12+ or jquery 2.2+.

本文标签: jqueryModifying svg attributes with javascript has no effectStack Overflow