使用 javascript 修改 svg 属性不起作用

Modifying svg attributes with javascript has no effect

本文关键字:属性 不起作用 svg 修改 javascript 使用      更新时间:2023-09-26

我正在尝试使用 javascript 修改 svg 标签以使其可调整大小,但我的更改不起作用。我需要这样做的原因是这个标签是由我无法修改的库渲染的,因此似乎我唯一的选择是使用 javascript 修改 svg。

我知道这个脚本生成的标签是正确的,因为我能够将标签复制到一个新的 html 文档中并且它会工作(我已将其包含在示例代码中),所以似乎我需要某种方法来强制 svg 识别它已被更改(或另一种修改 svg 的方法)。

这是一个显示我问题的 HTML 页面:

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

SVG 区分大小写,因此

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

应该写

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

<svg>元素上的宽度和高度是属性而不是样式(与 HTML 不同),因此您应该使用 setAttribute('width', '100%') 而不是.css('width', '100%')

jQuery

属性名称转换为小写;例如,它不是设置viewBox属性,而是设置viewbox。遗憾的是,SVG(一种 XML 方言)元素属性名称区分大小写。

如果你想一致地使用 jQuery,你可以使用 $.attrHooks 来处理区分大小写的属性:

['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'
  })
});

请注意,el.attr('viewBox', null)会失败;不会调用您的钩子设置器。相反,您应该使用 el.removeAttr('viewBox')el.attr('viewBox', false) .

对于其他属性,如笔画,我会将它们放在样式表中。

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

如果需要添加/切换类来更改特定元素的样式,则需要使用 jQuery 1.12+ 或 jquery 2.2+。