蛋疼的SVG外部引用方式
SVG在html页面中有两种引用方式:
1. 内联。就是直接将SVG图形写在html的svg标签中,比如:
<html> <head></head> <body> <svg ...> > ... > 内联式 </svg> > </body> </html>
2. 外部引用。就是以img标签,embed标签,object标签或iframe标签引用外部的svg文件,比如:
<html> <head></head> <body> <img src="sample.svg"> > <embed src="sample.svg"></embed> > 外部引用式 <iframe src="sample.svg"></iframe> > <object data="sample.svg"></object> > </body> </html>
对于以img标签形式的外部引用,将不支持脚本访问内部元素,仿佛真的就变成“img”了,因此仅适用于静态使用场景,应用范围比较有限。而其他几种方式都支持脚本访问。
那么问题来了,有这么多种引用方式,究竟哪种比较好呢?
经过这几天对SVG的折腾,我发现:对于静态使用场景,无所谓。对于动态使用场景,推荐内联方式,外部引用方式有不少坑。
内联方式可以满足你的任何需求:
1. 可以直接使用Javascript进行DOM操作(注意,Jquery也可以哦,但有些方法没有效果,因为SVG和HTML的DOM不同)
2. 可以直接使用CSS修饰
换句话说,用内联方式引用的SVG就跟普通HTML标签没什么区别!
唯一的不爽嘛,就是SVG的代码必须硬编码进HTML页面中,看着不爽,灵活性也差。
外部引用就比较悲剧了:
1. 无法直接使用Javascript进行DOM操作。
直接调用getElement系列方法得到的是引用的那个标签而不是SVG内容,比如:
<object id="svg-sample" src="sample.svg"></object>
你用document.getElementById("svg-sample")得到的只是object那个标签,而sample.svg的内容是没有的。为了得到svg的内容,必须还得通过contentDocument属性或getSVGDocument()方法。像这样:
document.getElementById("svg-sample").contentDocument
或是
document.getElementById("svg-sample").getSVGDocument()
(getSVGDocument是个被废弃的方法,不推荐使用)
但是要注意,上面这个方法只对XHTML类型的页面有效,Content-Type得是application/xhtml+xml,否则对于text+html类型的页面还是取不到SVG的内容。因此,在本地调试的时候,还要对服务器进行特殊配置,使其返回正确类型的页面。好蛋疼。只有取到SVG的内容,才能够继续使用Javascript操纵内部元素。
可以参考StackOverflow上这个问题
2. 无法直接用CSS修饰
这个好解决,在SVG内部引入外部CSS即可。但我最开始被这个问题困扰了很久。。一直不知道原因。
SVG成为标准都10多年了,没想到直到今天用起来还这么蛋疼。。