javascript 使用 svg 设置属性的更简单方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21361570/
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
Simpler way to set attributes with svg?
提问by CRABOLO
I'm new to SVG
, so I apologize in advance for my ignorance.
我是新手SVG
,所以我提前为我的无知道歉。
I created a fiddle, just playing around with things. http://jsfiddle.net/a46p8/
我创造了一个小提琴,只是玩弄东西。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);
Is there really no simpler way to setAttributes? For example, is it at all possible to combine them with something like this:
真的没有更简单的方法来设置属性吗?例如,是否有可能将它们与这样的东西结合起来:
line.setAttribute('x1', '0', 'y1', '0', 'x2', '150', 'y2', '150');
Yea, I know it doesn't work when I try in the fiddle. But is there some way to do it? If not, what's the reason why you can't?
是的,我知道当我尝试小提琴时它不起作用。但是有什么方法可以做到吗?如果没有,你不能的原因是什么?
采纳答案by Matt
Writing your own function would be a solution. As for your example of line.setAttribute('x1', '0', 'y1', '0', 'x2', '150', 'y2', '150');
, this would work, but it's going to be difficult to modify, and will expect that the parameters as passed in a particular order.
编写自己的函数将是一个解决方案。至于您的 示例line.setAttribute('x1', '0', 'y1', '0', 'x2', '150', 'y2', '150');
,这会起作用,但将很难修改,并且期望参数以特定顺序传递。
I would have a function that accepts a single object:
我会有一个接受单个对象的函数:
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;
}
So, all together it would look something like this:
所以,总的来说,它看起来像这样:
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);
If you're looking to go deeper then this and you need to do a lot of work with SVG in your project then a framework would probably be a worth considering.
如果您想更深入地了解这一点,并且需要在项目中使用 SVG 进行大量工作,那么框架可能值得考虑。
回答by CRABOLO
Taking susheel's advice, I wrote this function. It works, definitely will be a lot shorter to create new lines when need be now. But this probably isn't the best way to do it I'm guessing. Thoughts?
根据 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);
EDIT:
编辑:
Better option:
更好的选择:
This is expanding on Matt's answer, adding so there's a complete example for future readers.
这是对马特的回答的扩展,添加了一个完整的例子供未来的读者使用。
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})
回答by Ian
If you would want a simpler way, I would personally look into Snap.svg (for more modern browsers), or Raphael.js (for older), svg.js, pablo.js, d3.js etc. They are basically doing a similar thing behind the scenes, so others have already made it easier for you.
如果您想要更简单的方法,我会亲自查看 Snap.svg(对于更现代的浏览器)或 Raphael.js(对于较旧的)、svg.js、pablo.js、d3.js 等。他们基本上是在做幕后类似的事情,所以其他人已经让你更容易了。
So for Snap it would look like...
所以对于 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/
jsfiddle http://jsfiddle.net/38jrG/2/
If you really don't want to use a lib to make things easier, just write a func for each like susheel suggests.
如果你真的不想使用 lib 来简化事情,只需像 susheel 建议的那样为每个人写一个 func 。
回答by jave.web
ES8 = ECMAScript 8 (2017)
ES8 = ECMAScript 8 (2017)
The forEach
arrow-function way with Object.entries()
该forEach
箭头功能与方式Object.entries()
If you want to do it by yourself, there is no native way that I know of, however you can, as other suggested, create your own function that would get the element and object of property => value pairs and would loop over the keys and do it the native way for you.
如果你想自己做,我知道没有本地方式,但是你可以像其他人建议的那样创建自己的函数来获取属性 => 值对的元素和对象,并循环遍历键并按照您的本地方式进行操作。
ES8 - ECMAScript 2017 (8th Edition ECMA-262) brought
ES8 - ECMAScript 2017(第 8 版 ECMA-262)带来
Object.entries(object)
which gives you nicearray
ofarray
s of[key, value]
Object.entries(object)
它给你很好array
的array
第[key, value]
ES6 - ECMAScript 2015 (6th Edition, ECMA-262) brought
ES6 - ECMAScript 2015(第 6 版,ECMA-262)带来
- nice forEach on arrays
- a shorter way to write anonymous callbacks/functions - "arrow functions"
- 漂亮的数组的forEach
- 编写匿名回调/函数的更短方法 - “箭头函数”
If you combine these 3, you get a really elegant modern solution to do that:
如果您将这 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 - minified oneliner
TL;DR - 缩小的单线
var setAttrs = (e,a)=>Object.entries(a).forEach(([k,v])=>e.setAttribute(k,v));
USAGE:
用法:
setAttrs(element, {attribute1: value1, ...}