【问题标题】:Simpler way to set attributes with svg?使用 svg 设置属性的更简单方法?
【发布时间】:2023-03-31 18:15:02
【问题描述】:

我是SVG 的新手,所以我提前为我的无知道歉。

我创造了一个小提琴,只是在玩弄一些东西。 http://jsfiddle.net/a46p8/

var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
svg.setAttribute('width','200');
svg.setAttribute('height','200');


var line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
line.setAttribute('width', '0');
line.setAttribute('height', '0');
line.setAttribute('x1', '0');
line.setAttribute('y1', '0');
line.setAttribute('x2', '150');
line.setAttribute('y2', '150');
line.setAttribute('stroke', 'rgb(255,0,0)');
line.setAttribute('stroke-width', '2');

svg.appendChild(line);

var ct = document.getElementById('container'); 
ct.appendChild(svg);

真的没有更简单的setAttributes方法吗?例如,是否有可能将它们与这样的东西结合起来:

line.setAttribute('x1', '0', 'y1', '0', 'x2', '150', 'y2', '150');

是的,我知道当我尝试小提琴时它不起作用。但是有什么方法可以做到吗?如果不是,那是什么原因你不能呢?

【问题讨论】:

  • 编写自己的函数...

标签: javascript svg setattribute


【解决方案1】:

编写自己的函数将是一个解决方案。至于您的line.setAttribute('x1', '0', 'y1', '0', 'x2', '150', 'y2', '150'); 示例,这将起作用,但将很难修改,并且期望参数以特定顺序传递。

我会有一个接受单个对象的函数:

function Line(obj){
    var line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
    for(prop in obj) {
        line.setAttribute(prop, obj[prop])  
    }
    return line;
}

function SvgContainer(obj) {
    var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
    for(prop in obj) {
        svg.setAttribute(prop, obj[prop])  
    }
    return svg;
}

所以,总的来说,它看起来像这样:

var svgParent = new SvgContainer({
    'width': 200,
    'height': 200
});

var lineOne = new Line({
    'width': 0,
    'height': 0,
    'x1': 0
        // etc
});

var ctn = document.getElementById('container');
svgParent.appendChild(lineOne);
ctn.appendChild(svgParent);

如果您想要更深入地了解这一点,并且您需要在项目中使用 SVG 做大量工作,那么框架可能值得考虑。

【讨论】:

    【解决方案2】:

    听从 susheel 的建议,我编写了这个函数。它有效,现在需要时创建新行肯定会短得多。但这可能不是我猜的最好方法。想法?

    var line, line2;
    
    var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
    svg.setAttribute('width', 1000);
    svg.setAttribute('height', 400);
    
    
    function makeLines(name, xs, ys, xe, ye, color, sw) {
        name = document.createElementNS('http://www.w3.org/2000/svg', 'line');
        name.setAttribute('x1', xs);
        name.setAttribute('y1', ys);
        name.setAttribute('x2', xe);
        name.setAttribute('y2', ye);
        name.setAttribute('stroke', color);
        name.setAttribute('stroke-width', sw);
    
        svg.appendChild(name);
        var cnt = document.getElementById('container');
        cnt.appendChild(svg);
    }
    
    makeLines(line, 100, 0, 900, 200, 'blue', 8);
    makeLines(line2, 700, 450, 200, 100, 'red', 2);
    

    编辑:

    更好的选择:

    这是对马特的回答的扩展,添加了一个完整的示例供未来的读者使用。

    var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
    svg.setAttribute('width', 1000);
    svg.setAttribute('height', 400);
    
    function Line(obj) {
        var line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
        for(prop in obj) {
            line.setAttribute(prop, obj[prop])  
        }
        svg.appendChild(line);
        var ctn = document.getElementById('container');
        ctn.appendChild(svg);
    }
    
    var aline = new Line({
        'x1': 0,
        'y1': 0,
        'x2': 600,
        'y2': 200,
        'stroke': 'green',
        'stroke-width': 8
    })
    
    
    var aline2 = new Line({'x1': 500,'y1': 0,'x2': 100,'y2': 400,'stroke': 'red','stroke-width': 2})
    

    【讨论】:

    • 我会在 Line 构造函数之外追加新行(请原谅,我在最初的回答中省略了 return 表达式。
    【解决方案3】:

    如果您想要更简单的方法,我个人会研究 Snap.svg(适用于更现代的浏览器)或 Raphael.js(适用于较旧的浏览器)、svg.js、pablo.js、d3.js 等。它们是基本上在幕后做类似的事情,所以其他人已经让你更容易了。

    所以对于 Snap,它看起来像......

    var s = Snap(400,400);
    var l = s.line(0,0,150,150).attr({ stroke: 'rgb(255,0,0)', 'stroke-width': 2 }); 
    

    jsfiddle http://jsfiddle.net/38jrG/2/

    如果您真的不想使用 lib 来简化事情,只需像 susheel 建议的那样为每个库编写一个 func。

    【讨论】:

      【解决方案4】:

      ES8 = ECMAScript 8 (2017)

      forEach 箭头函数方式与Object.entries()

      如果你想自己做,我知道没有本地方法,但是你可以像其他人建议的那样,创建你自己的函数来获取属性 => 值对的元素和对象并循环在按键上,并为您以本机方式进行操作。

      ES8 - ECMAScript 2017(第 8 版 ECMA-262)带来

      ES6 - ECMAScript 2015(第 6 版,ECMA-262)带来

      如果将这 3 个结合起来,您将获得一个非常优雅的现代解决方案:

      // FUNCTION
      var setAttributes = (el, atts) => {
          Object.entries(atts).forEach(([key, value]) => { // note () around [k,v]!!!
              el.setAttribute(key, value);
          });
      };
      // USAGE
      setAttributes(line, {
         'x1' : 0,
         'y1' : 0,
         // ...
      });
      

      TL;DR - 缩小的 oneliner

      var setAttrs = (e,a)=>Object.entries(a).forEach(([k,v])=>e.setAttribute(k,v));
      

      用法:

      setAttrs(element, {attribute1: value1, ...}
      

      【讨论】:

        【解决方案5】:

        对@Matt 的改进,我有这个实用程序类。

        class zintSvgUtil{
        
            static createSVGElement(type, obj) {
                let el = document.createElementNS('http://www.w3.org/2000/svg', type);
                for (let prop in obj) {
                    el.setAttribute(prop, obj[prop])
                }
                return el;
            }
        
        }
        

        那么,

        const svgParent = zintSvgUtil.createSVGElement("svg", {
            width: 200,
            height: 250,
            viewBox: "0 0 200 250"
        });
        
        const lineOne = zintSvgUtil.createSVGElement("line", {
            x1: 0,
            y1: 0,
            x2: 100,
            y2: 150,
            stroke: "blue",
            "stroke-width": 2
        })
        
        let element = document.querySelector('#idA');
        svgParent.appendChild(lineOne);
        element.appendChild(svgParent);
        

        【讨论】:

        • 请解释这将如何成为一种改进,以及为什么它不仅仅需要对已接受的答案发表评论。
        • 我认为在一个类下收集这种实用程序是一种很好的编程习惯。除此之外,我同意它也可以是评论。我无动于衷。谢谢。
        猜你喜欢
        • 1970-01-01
        • 2013-12-23
        • 1970-01-01
        • 2011-02-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-25
        • 1970-01-01
        相关资源
        最近更新 更多