SVG Sprite(这里特指基于svg symbol)做为传统css sprite和icon font的替代方案,在现代浏览器(ie9+)上可以正常运行,关于它的技术背景、特色和降级方案等再也不赘述,能够参考如下几篇文章,写的都很是不错:javascript
面向将来的图标图片精灵jquery
在具体实践过程当中,遇到如下两个问题:css3
IE浏览器不支持外链svg sprite文件,也就是说svg sprite必须嵌入到页面里面(最前面)git
IE浏览器下,拥有use标签到svg元素上到点击事件没法冒泡,现象是在使用代理的方式绑定事件时(绑定到svg元素的父元素上,绑定到svg元素自己就更没办法了),点击svg元素自己没法触发点击事件。github
下面就这两个问题逐个看看解决方案。gulp
咱们一是要保证ie下svg sprite图标能正常显示,因此必须采用嵌入到页面的方案,同时还要解决缓存的问题,若是直接放在模版文件里,那每次都须要从新下载,就失去了原来css spirte和icon font能够缓存的特色。浏览器
这里我采用的方案是本地利用构建工具(我用的是基于grunt的grunt-svg-sprite,gulp也有对应的插件)生成svg sprite文件,而后单独在页面最前面放一个js文件,js文件包含svg sprite的内容,并在自身加载完成后把svg sprite插入到页面最前面。
tpl:
<body> <script type="text/javascript" src="/static/js/svgsprite.js" async></script> ... </body>
svgsprite.js:
// 构建工具生成的svg sprite文件 var svgsprite = require('./svg/symbol/svg/sprite.symbol.svg'); document.body.insertAdjacentHTML( 'afterBegin', // 插入body第一个子节点前面 '<div class="hide">' + svgsprite + '</div>' );
browserify配置:
// 是svg文件能够做为string类型被require brs.transform(stringify(['.svg']));
由于js文件是能够缓存的,因此至关于变相把svg sprite缓存起来了。
第二个问题比较棘手一点,关于这个问题,jquery开发人员也作了解答:
Delegated event not firing for click within SVG use element
前面说了是因为包含use标签的svg元素没法冒泡,那么直接在svg元素或者svg父元素上绑定事件就能够了,可是在涉及新增、删除等操做时,可操做的按钮都是动态添加的,若是每次添加元素都要从新绑定事件,是很是麻烦的。
幸亏有pointer-events
这个神器,这是css3的新属性,虽然对于普通html元素的支持性不是太好,但对于支持svg的浏览器,基本都支持这个属性。
http://caniuse.com/#search=pointer-events
Already part of the SVG specification, and all SVG-supporting browsers appear to support the property on SVG elements.
经过对svg元素应用pointer-events:none
,可让svg相对点击事件“透明”,只要事件绑定到svg的父元素上,且父元素具有宽高(须要设置为inline-block,或者应用float、position:absolute等,不然ie下点不中)。
针对以上需求,我写了个简单的sass mixin:
@mixin svg-sprite( $width, $heigth, $fill: default, $hover-fill: default ) { display: inline-block; width: $width; height: $heigth; svg.g-ico { width: $width; height: $heigth; pointer-events:none; } @if $fill != default { svg { fill: $fill; } } @if $hover-fill != default { &:hover { // tips: hover是在父元素上 svg { fill: $hover-fill; } } } }
给svg元素的父元素应用这个mixin,这样就算是圆满解决了这个问题。
Tips: 由于咱们的网站兼容ie9+,因此ie9如下的没有作降级处理,若是须要,能够参考前面列出的几篇文章。