使用svg设置属性的更简单方法?

时间:2014-01-26 08:59:42

标签: javascript svg setattribute

我是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');

是的,我知道当我尝试小提琴时它不起作用。但有没有办法做到这一点?如果没有,你不能的原因是什么?

5 个答案:

答案 0 :(得分:6)

编写自己的函数将是一个解决方案。至于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进行大量工作,那么框架可能值得考虑。

答案 1 :(得分:2)

如果你想要一种更简单的方法,我会亲自调查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建议的那样为每个人编写一个函数。

答案 2 :(得分:1)

根据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);

编辑:

更好的选择:

这正在扩展Matt的答案,并为未来的读者提供了一个完整的例子。

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

答案 3 :(得分:0)

ES8 = ECMAScript 8(2017)

带有$result = sendMail($email); if($result == 1) { return redirect('/')->with("msg", $response); } else { return redirect('/')->with("msg", $badResponse); } function sendMail($email) { //... if($mail->send){ $result = 1; } else { $result = 2; } return $result; } 的{​​{1}}箭头功能方式

如果您想自己做,就没有我知道的本机方法,但是,正如其他建议那样,您可以创建自己的函数,该函数将获取属性=>值对的元素和对象并循环在键上,然后为您完成本机操作。

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

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

如果将这三个方法结合使用,您将获得一个非常优雅的现代解决方案:

array

TL; DR-最小的单线纸

[key, value]

用法:

// 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,
   // ...
});

答案 4 :(得分:-1)

对@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);