我有这个带路径的SVG容器。我想编辑它,所以路径的填充将是一个模式。这是我失败的尝试:
我添加渐变:
$('svg defs').prepend('<linearGradient id="MyGradient"><stop offset="5%" stop-color="#F60" /><stop offset="95%" stop-color="#FF6" /></linearGradient>');
然后更改路径的填充:
$(base + ' svg path').each(function() {
this.setAttribute('fill','url(#MyGradient)')
}
这不起作用。我错过了什么?
答案 0 :(得分:21)
你的问题(你“缺少”)是jQuery在XHTML命名空间中创建新元素,而SVG元素必须在SVG命名空间中创建。您不能在SVG元素的字符串中使用原始代码。
最简单的(无插件)方法是停止依赖jQuery这么多,只需使用简单的DOM方法来创建元素。是的,它比仅仅使用jQuery为你神奇地构建元素更加冗长......但是在这种情况下jQuery不起作用。
createGradient($('svg')[0],'MyGradient',[
{offset:'5%', 'stop-color':'#f60'},
{offset:'95%','stop-color':'#ff6'}
]);
$('svg path').attr('fill','url(#MyGradient)');
// svg: the owning <svg> element
// id: an id="..." attribute for the gradient
// stops: an array of objects with <stop> attributes
function createGradient(svg,id,stops){
var svgNS = svg.namespaceURI;
var grad = document.createElementNS(svgNS,'linearGradient');
grad.setAttribute('id',id);
for (var i=0;i<stops.length;i++){
var attrs = stops[i];
var stop = document.createElementNS(svgNS,'stop');
for (var attr in attrs){
if (attrs.hasOwnProperty(attr)) stop.setAttribute(attr,attrs[attr]);
}
grad.appendChild(stop);
}
var defs = svg.querySelector('defs') ||
svg.insertBefore( document.createElementNS(svgNS,'defs'), svg.firstChild);
return defs.appendChild(grad);
}
或者,您可以包含Keith Woods' "jQuery SVG" plugin,其中包含许多常用SVG操作的便捷方法,包括create linear gradients的功能。
答案 1 :(得分:3)
我认为你必须使用jQuery的SVG插件(找到here)。使用“普通”jQuery库添加SVG元素时,名称空间可能会混淆。
尝试以下方法:
svg.linearGradient( $('svg defs'),
'MyGradient',
[ ['5%', '#F60'], ['95%', '#FF6']] );
(但不完全确定。您可能需要对该代码进行一些调整。)
修改强> 的
刚刚创建了这个fiddle以测试论文(正如@Phrogz所建议的那样)。实际上,它返回http://www.w3.org/1999/xhtml
作为插入的<linearGradient>
的命名空间,这是错误的命名空间,从而验证了我的上述推测。
答案 2 :(得分:3)
找到解决方案。 它有点难看,但不需要使用额外的插件。
显然,首次创建SVG时,必须在标签中包含一个模式(可能只读取它)。
因此,用自己替换SVG标记的包装器内容是有效的(base
是该包装器):
$(base).html($(base).html())
答案 3 :(得分:3)
我只想说,我已经找到了一个更优雅的解决方案,它允许你继续使用jQuery与SVG元素,但没有jQuery SVG库(不再更新,并且jQuery 1.8或更高版本有一些问题)。 只需使用这样的函数:
createSVGElement= function(element) {
return $(document.createElementNS('http://www.w3.org/2000/svg', element));
}
它在SVG命名空间上创建一个SVG元素,并用jQuery封装它,一旦在正确的命名空间中创建了元素,就可以在jQuery中自由使用它:
然后您可以这种方式使用该功能:
var $myGradient= createSVGElement('linearGradient')
.attr( {
id:"MyGradient"
});
//if you dont need `defs`, skip this next line
var $myDefs = createSVGElement('defs');
createSVGElement('stop')
.attr({
offset: "5%",
"stop-color": "#F60"
})
.appendTo($myGradient);
createSVGElement('stop')
.attr({
offset:"95%",
"stop-color":"#FF6"
})
.appendTo($myGradient);
//Use this if you already have `defs`
$('svg defs').prepend($myGradient);
//Use this if you dont have `defs`
$('svg').prepend($myDefs);
$('svg defs').prepend($myGradient);
它不像你想要的那样紧凑,因为你必须手工创建每个元素,但它比使用DOM方法操作所有元素要好得多。
小注释,jQuery .attr()函数假定所有属性都是小写的,而SVG元素则不是这种情况(例如viewBox
标记中的<svg>
属性)。为了解决这个问题,当使用大写字母设置属性时,请使用以下内容:
$("svg")[0].setAttribute("viewBox", "0 0 1000 1000");