引入 SVG 多色图标的最简便方法

前言

几种常见的字体图标引用方法可以看这篇文章

普通的单色字体图标的引用方法往往很简便,像这样:

<!-- unicode 引用 -->
<i class="iconfont">&#x33;</i>

<!-- 类名 引用 -->
<i class="iconfont icon-xxx"></i> 

但是多色图标有多图层,就没法直接以字体的形式外加 CSS那样简便地引用了。

既然CSS不行那就用JS


Symbol 引用

正如其名,Symbol 引用方式不同于一般的使用,使用时写下的只是该图标的 Symbol(象征),然后用JS将 Symbol 替换为真正的SVG。既保证了书写的简便,又实现了完整的SVG效果。

iconfont+ 对于多色图标就提供了这种方法。

这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇文章
这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:

  • 支持多色图标了,不再受单色限制。
  • 通过一些技巧,支持像字体那样,通过 font-size, color 来调整样式。
  • 兼容性较差,支持 IE9+,及现代浏览器。
  • 浏览器渲染 SVG 的性能一般,还不如 png。

引用时像这样写:

<svg class="icon" aria-hidden="true">
    <use xlink:href="#icon-xxx"></use>
</svg> 

比较简便,但JS实现的缺点也很明显:无法做到像CSS那样的实时刷新,动态添加、动态改变的图标不会正常显示,直到重新运行JS


一些改进

JS无法像CSS那样实时更新,这难以改变(setInterval又显得不优雅)。

不过既然已经是Symbol了,为何不然它更简便些呢

最简单的实现方法,是先用iconfont+生成图标包,再对它的 Symbol 进行封装

iconfont的项目里,点击下载至本地,它会把这个项目相关的字体文件都下载下来。找到下载下来里面的iconfont.js文件,进行修改。

比如:

我希望引用时只需要 像单色字体图标那样,写下<i>标签与类名:

<i class="icon-xxx"></i> 

于是JS像这样,运行时把它替换为iconfont+的 Symbol :

$('i.icon-xxx').after(
    $('<svg class="icon" aria-hidden="true"><use xlink:href="#icon-xxx"></use></svg>')
).remove(); 

后面再接iconfont+的代码。

当然,一个图标包那么多图标,实际使用时还是要用 for 循环来实现。

我是这样写的:

var iconNameList = [
    'icon-1',
    'icon-2',
    /* 此处省略若干个图标名 */
    /* ...... */
    'icon-xxx',
];
for (let i in iconNameList) {
    let name = iconNameList[i];
    if ($('i.' + name).length) { /* 如果页面中有这个图标 */
        $('i.' + name).after( /* 替换 Symbol */
            $('<svg class="icon" aria-hidden="true"><use xlink:href="#' + name + '"></use></svg>')
        ).remove();
    }
}
/* 后接iconfont+的代码 */

这样,引用时只需要像普通字体图标那样写,是不是很简便


另外,为了正常显示,它需要一些CSS属性:

.icon {
       width: 1em; height: 1em;
       vertical-align: -0.15em;
       fill: currentColor;
       overflow: hidden;
} 

为了使用简便,可以将它集成到JS

$('head').append(
    $('<style type="text/css">.icon {width: 1em; height: 1em; vertical-align: -0.15em; fill: currentColor; overflow: hidden;}</style>')
); 

此博客所有文章默认采用署名—非商业性使用—相同方式共享 4.0 协议进行许可
本文链接:https://blog.texice.xyz/2020/%E7%AE%80%E4%BE%BF%E5%BC%95%E7%94%A8%E5%A4%9A%E8%89%B2%E5%9B%BE%E6%A0%87/