为什么我不能引用在外部文件(绘画服务器)中定义的 SVG 线性渐变?
Why can't I reference an SVG linear gradient defined in an external file (paint server)?
请看这支笔:
http://codepen.io/troywarr/pen/VYmbaa
我在这里做的是:
- 定义 SVG 符号 (
<symbol>
)
- 定义 SVG 线性渐变 (
<linearGradient>
)
- 使用
<use>
元素引用我创建的 SVG 符号
- 在CSS中,定义了两个class:
external
,它引用了this external .svg
file中定义的线性渐变(右键单击并查看源代码)
internal
,它引用了本地 HTML 中定义的线性渐变(我相信,这实际上与外部文件中的相同)
因为我已经将 internal
class 应用到 HTML 示例底部的 <svg>
元素,所以应用了渐变,呈现蓝色渐变复选标记。这就是我所追求的。
但是,如果在 HTML 示例中将 internal
class 切换为 external
,则复选标记不再可见:
http://codepen.io/troywarr/pen/vEymKX
当我查看 Chrome Inspector 的 "Network" 选项卡时,我根本没有看到浏览器试图加载 SVG 文件。我的语法有问题,还是这里发生了什么?
根据我发现的一些参考资料,至少看起来我做对了:
- http://www.w3.org/TR/SVG/painting.html#SpecifyingPaint
- http://www.w3.org/TR/SVG/linking.html#IRIReference
但是,到目前为止,我所做的任何尝试都无法引用外部 .svg
文件中定义的线性渐变。
感谢您的帮助!
经过更多研究,这似乎是浏览器支持问题。参见:
- https://code.google.com/p/chromium/issues/detail?id=109212
- https://bugs.webkit.org/show_bug.cgi?id=105904
可悲的是,我在发布我的帖子之前遇到了 this question,并且认为在 5-1/2 年内,浏览器支持肯定会赶上来 - 但似乎并没有案.
截至 2015 年,显然 Firefox 和 Opera 是仅有的两个以任何实质性方式支持此功能的浏览器。
回到绘图板...
您可以将 svg4everybody 与 polyfill: true
选项一起使用,它将插入所有外部符号而不是 use
标签。但是会引起第二次svg加载。
因此您可以使用 ajax 请求下载 svg,然后将其插入到隐藏样式的页面中。
<script>var ajax=new XMLHttpRequest;ajax.open("GET","/img/svg-sprite.svg",!0),ajax.send(),ajax.onload=function(a){var b=document.createElement("div");b.classList.add("hidden"),b.innerHTML=ajax.responseText,document.body.insertBefore(b,document.body.childNodes[0])};</script>
在这种情况下:
/img/svg-sprite.svg — 是你的 svg 路径。
.隐藏 class 样式:
.hidden {
position: absolute !important;
width: 1px;
height: 1px;
overflow: hidden;
clip: rect(1px, 1px, 1px, 1px);
}
您的代码可能如下所示:
<svg><use xlink:href="#logo"></use></svg>
请看这支笔:
http://codepen.io/troywarr/pen/VYmbaa
我在这里做的是:
- 定义 SVG 符号 (
<symbol>
) - 定义 SVG 线性渐变 (
<linearGradient>
) - 使用
<use>
元素引用我创建的 SVG 符号 - 在CSS中,定义了两个class:
external
,它引用了this external.svg
file中定义的线性渐变(右键单击并查看源代码)internal
,它引用了本地 HTML 中定义的线性渐变(我相信,这实际上与外部文件中的相同)
因为我已经将 internal
class 应用到 HTML 示例底部的 <svg>
元素,所以应用了渐变,呈现蓝色渐变复选标记。这就是我所追求的。
但是,如果在 HTML 示例中将 internal
class 切换为 external
,则复选标记不再可见:
http://codepen.io/troywarr/pen/vEymKX
当我查看 Chrome Inspector 的 "Network" 选项卡时,我根本没有看到浏览器试图加载 SVG 文件。我的语法有问题,还是这里发生了什么?
根据我发现的一些参考资料,至少看起来我做对了:
- http://www.w3.org/TR/SVG/painting.html#SpecifyingPaint
- http://www.w3.org/TR/SVG/linking.html#IRIReference
但是,到目前为止,我所做的任何尝试都无法引用外部 .svg
文件中定义的线性渐变。
感谢您的帮助!
经过更多研究,这似乎是浏览器支持问题。参见:
- https://code.google.com/p/chromium/issues/detail?id=109212
- https://bugs.webkit.org/show_bug.cgi?id=105904
可悲的是,我在发布我的帖子之前遇到了 this question,并且认为在 5-1/2 年内,浏览器支持肯定会赶上来 - 但似乎并没有案.
截至 2015 年,显然 Firefox 和 Opera 是仅有的两个以任何实质性方式支持此功能的浏览器。
回到绘图板...
您可以将 svg4everybody 与 polyfill: true
选项一起使用,它将插入所有外部符号而不是 use
标签。但是会引起第二次svg加载。
因此您可以使用 ajax 请求下载 svg,然后将其插入到隐藏样式的页面中。
<script>var ajax=new XMLHttpRequest;ajax.open("GET","/img/svg-sprite.svg",!0),ajax.send(),ajax.onload=function(a){var b=document.createElement("div");b.classList.add("hidden"),b.innerHTML=ajax.responseText,document.body.insertBefore(b,document.body.childNodes[0])};</script>
在这种情况下:
/img/svg-sprite.svg — 是你的 svg 路径。
.隐藏 class 样式:
.hidden {
position: absolute !important;
width: 1px;
height: 1px;
overflow: hidden;
clip: rect(1px, 1px, 1px, 1px);
}
您的代码可能如下所示:
<svg><use xlink:href="#logo"></use></svg>