使用 javascript 修改 svg 属性无效

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10973339/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 03:50:56  来源:igfitidea点击:

Modifying svg attributes with javascript has no effect

javascriptjqueryhtmlsvg

提问by Nocklas

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.

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

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

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

Here's a HTML page that shows my problem:

这是一个显示我的问题的 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>

回答by Robert Longson

SVG is case sensitive so

SVG 区分大小写,所以

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%')

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

回答by Dinoboff

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

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

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

如果您想始终如一地使用 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'
  })
});

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

注意那el.attr('viewBox', null)会失败;你的钩子二传手不会被调用。相反,您应该使用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+.

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