如何访问独立文件中的SVG定义,实现多SVG文件复用?
问题描述
想要创建多个基于通用SVG定义的SVG文件,避免在每个文件中重复定义,尝试用<use href=...>结构从单独的定义文件中引用元素,但浏览器只显示当前SVG文件里的内容,无法加载外部定义的图形。
以下是简化的测试示例:
可正常工作的单文件示例(int.svg)
<?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"> <path d="M 0 50 L 100 50" stroke="black"/> <defs> <g id="g"> <circle cx="50" cy="50" r="50" stroke="black" fill="none"/> </g> </defs> <use href="#g"/> </svg>
这个文件在Brave浏览器中能正常显示带水平直径的圆形。
拆分后的文件
def.svg(单独存放定义)
<?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"> <defs> <g id="g"> <circle cx="50" cy="50" r="50" stroke="black" fill="none"/> </g> </defs> </svg>
ext.svg(尝试引用外部定义)
<?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"> <path d="M 0 50 L 100 50" stroke="black"/> <use href="def.svg#g"/> </svg>
此时浏览器仅显示ext.svg中的水平直径,不显示外部定义的圆形。
问题原因及解决方法
核心原因
- 本地
file://协议下,浏览器的同源策略会严格限制跨文件资源引用; - 部分浏览器会将外部SVG当作普通图像资源处理,不会解析其中的
<defs>元素,导致无法通过#id定位到定义内容。
可行解决方法
方法1:修改外部定义文件的根SVG属性
给def.svg的根<svg>设置不可见样式,让浏览器解析定义但不渲染整个SVG:
<?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" width="0" height="0" viewBox="0 0 100 100" style="display: none;"> <defs> <g id="g"> <circle cx="50" cy="50" r="50" stroke="black" fill="none"/> </g> </defs> </svg>
保持ext.svg中的<use>路径不变即可。
方法2:搭建本地服务器测试
如果是直接双击打开本地文件(file://协议),浏览器的跨域限制会阻止引用。可以用简单的本地服务器访问文件:
- 打开终端,进入文件所在目录
- 执行命令:
python -m http.server(Python3)或python -m SimpleHTTPServer(Python2) - 通过
http://localhost:8000/ext.svg访问,此时大部分情况下原始的def.svg和ext.svg就能正常工作。
方法3:使用SVG Sprite方案
这是更通用的复用SVG定义的方案,将所有通用定义放在一个"精灵文件"中:
sprite.svg
<?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <defs> <g id="g"> <circle cx="50" cy="50" r="50" stroke="black" fill="none"/> </g> <!-- 可添加更多通用SVG定义 --> </defs> </svg>
ext.svg引用
<?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"> <path d="M 0 50 L 100 50" stroke="black"/> <use href="sprite.svg#g"/> </svg>
内容的提问来源于stack exchange,提问作者Allan Wilks
相关产品推荐
相关产品推荐

