SVGInject插件动态加载SVG并自定义样式

HTML 中加载 SVG 有很多种方式,但如果需要在 HTML 中通过 CSS 样式自由控制 SVG 样式就必须将 svg 标签插入网页找那个成为 DOM 的一部分,本文借助 SVGInject 插件可以快速完成这一操作

所属分类 WEB

相关标签 CSSSVG标签

SVG特性

SVG 是一种图像文件格式,全称为 Scalable Vector Graphics,意思为可缩放的矢量图形。

SVG 采用 XML 定义语言,通过代码描述矢量/栅格/图形,很大程度上相同表现的 SVG 往往比其他格式图片更小。

SVG 图形是可以动态化与交互的,在 SVG 中嵌入动画元素或通过脚本来定义动画,比 gif 动态图片更加自由与灵活。

在 Web 应用中,可以通过操作 DOM 的方式去操作 SVG 元素,包括放大/缩小/偏移/改变颜色等。

由于 SVG 本身通过代码定义的矢量集,在任何分辨率下渲染方法或缩小都不会失真。

HTML加载SVG

HTML 中加载 svg 有如下几种方案:

  1. 将 <svg> 标签直接写入 HTML 的 DOM 结构中。
  2. 通过 <img> 标签的 src 属性指向 svg 文件。
  3. 通过 css 背景图片 url 属性指向 svg 文件。
  4. 通过 <object> <embed> <iframe> 等标签嵌入 svg 文件。
  5. 通过 JS 读取 svg 文件后写入 DOM 结构中。

CSS控制SVG

在 HTML 中想通过 CSS 控制 SVG 的样式,则 SVG 必须通过 <svg> 标签内联至 HTML 的 DOM 结构中。

因此,只有方式1和方式5可以满足要求。

方式1如果服务端直接存放的是静态 HTML 文件,就需要提前写入 SVG 节点,这非常不利于维护。

如果使用服务端组装 HTML,则需要执行预渲染操作,由服务端提前将 SVG 结构内容从数据库或者文件中读取出来写到 HTML 中再返回到客户端。

整体来看方式1将 SVG 直接耦合到 HTML 中可以实现,但是有不少缺点。

方式5中 SVG 资源还是保留在对应的 .svg 文件中,以静态图片资源的形式存在。

HTML 中可以通过 <img> 或者其他标签直接引入 SVG 文件,和正常加载图片的形式完全一致。

在引入 SVG 后可以通过 JS 去读取 SVG 文件的内容,通过操作 DOM 的方式将 SVG 节点插入到 DOM 中,继而可以通过 CSS 控制 SVG 样式。

整体来看方案5依旧保留了常规的 HTML 书写习惯,SVG 文件也可以按照标准放到静态资源目录下,后期修改 SVG 无需修改代码,更加利于维护和处理。

当确认采用 JS 加载 SVG 方案后,需要考虑以下问题:

  1. 在 SVG 源节点尚未写入 HTML 之前,界面应当能够正常展示图像(原始 SVG 的样式)。
  2. 最好能将 SVG 节点插入到一开始展示的位置。
  3. 通过预先写好的 CSS 样式控制 SVG 节点样式。

就当我准备造轮子的时候,发现这个轮子已经有人造好了...

SVGInject插件

下图为 SVGInject 的 GitHub 页的简介。

/static/upload/post/1647908146923.jpg

首先 HTML 网页中可以正常通过 <img> 标签指向 SVG 文件进行常规的 SVG 图像显示,这时无法通过样式控制 SVG 的样式。

通过 SVGInject 插件去加载 SVG 文件的源节点,并通过 <svg> 标签替换原本的 <img> 标签。

先定义好 <img> <svg> 元素的控制CSS:

/* 因为 svg 标签后期会替换 img 因此可以一起定义 */
.itm img,.itm svg{
    width: 60px;
    height: 60px;
    display:block;
    padding:5px;
}
/* 我加载的 SVG 文件中默认 fill:#fff */
.itm svg path{
    fill:#444;
}
/* 增加 hover 效果 缩小 */
.itm a:hover img,.itm a:hover svg{
    padding:8px;
}
/* SVG 节点变色 */
.itm a:hover svg path{
    fill:#539bf5;
}

HTML 中引入 JS 正常书写 <img> 加载 SVG:

<div class="box itm">
    <a href="/quck/team_java_1.html">
        <!-- onload 图片加载完成 启用 SVGInject 传入当前节点 -->
        <img src="/static/img/team/java.svg" onload="SVGInject(this)"/>
        <h2>JAVA</h2>
    </a>
</div>
<script src="/static/lib/svg/svg-inject.min.js?v=1.0"></script>

页面加载后的的效果如下图:

/static/upload/post/1647908333647.jpg

正常情况下,为了保证网页打开效率,我们往往会把 JS 文件放在最后引入。

由于 <img> 标签中直接绑定了 onload="SVGInject(this)",浏览器在解析网页元素时,由于位于底部的 JS 资源文件尚未加载完成,会出现找不到 SVGInject 方法有部分 SVG 元素报错而不被加载。

<!-- 指向我们自己定义的JS方法 -->
<img src="/static/java.svg" onload="initSvg(this)"/>
// WaitForSVGInjectInit
// 将该小段方法放在顶部,或者写一个公共的JS最先引入
function initSvg(obj) {
    try{
        SVGInject(obj);
    }catch(e){
        // 方法尚未实例化,执行递归
        setTimeout(function(){
            initSvg(obj);
        },200)
    }
}

下载一个最新的 TAG 即可:

https://github.com/iconfu/svg-inject/tags

米虫

做一个有理想的米虫,伪全栈程序猿,乐观主义者,坚信一切都是最好的安排!

本站由个人原创、收集或整理,如涉及侵权请联系删除

本站内容支持转发,希望贵方携带转载信息和原文链接

本站具有时效性,不提供有效、可用和准确等相关保证

本站不提供免费技术支持,暂不推荐您使用案例商业化

发表观点

提示

昵称

邮箱

QQ

网址

当前还没有观点发布,欢迎您留下足迹!

同类其他

WEB

nvm管理node.js和npm多版本切换

在业务中我们会出现不同的项目依赖与不同版本的 node.js,总不能每次跑项目的时候都去重新安装对应版本的 node.js 和依赖,使用 nvm 可以让多个版本的 node.js 共存,并提供管理和切换

Jquery中bind()、live()、delegate()和on()的区别

自Jquery1.7起,on()方法是 bind()、live()、delegate() 方法的新的替代品,我们推荐使用on()来处理业务中的事件绑定,通过理解这些方法的差异能够更加清晰明白使用on()方法的优势所在

Jquery.bind()实现前端字段公共校验器

严谨的页面开发需要着重关注前台校验相关的内容,确保请求参数的合法以保证服务器安全,界面参数众多需要建立一个公共方法,公共校验器的核心方法是Jquery.bind()

Jquery+CSS轻松实现导航动态显示隐藏

绝大多数网站都会有个顶部导航,对于手机端而言为了便于访问导航常常会做固顶操作,通过CSS样式配合Jquery的scroll()方法或原生JS监听滑动事件方法,可以轻松实现下滑隐藏,上滑显示的效果

前端JS对字段编码预防XSS攻击

跨站脚本攻击是比较严重的一种攻击行为,恶意脚本注入到相关页面字段中轻易获取敏感信息和向后端发起请求,前端应用应当对请求数据进行编码

通过Vuex实现全局状态管理

Vuex 是一个专为 Vue 应用程序开发的状态管理模式,通过集中式存储应用所有组件的状态,依照规则确保状态可以进行标准方式变化,比较适合应用在公共基础数据存放,如:用户信息

选择个人头像

昵称

邮箱

QQ

网址

评论提示

  • 头像:系统为您提供了12个头像自由选择,初次打开随机为你选择一个
  • 邮箱:可选提交邮箱,该信息不会外泄,或将上线管理员回复邮件通知
  • 网址:可选提交网址,评论区该地址将以外链的形式展示在您的昵称上
  • 记忆:浏览器将记忆您已选择或填写过得信息,下次评论无需重复输入
  • 审核:提供一个和谐友善的评论环境,本站所有评论需要经过人工审核