一个页面里GIF动画“联动”的问题

我们在前端页面里通常会使用GIF/WEBP图片显示一些动画来增加页面的丰富程度及交互体验,一般来说一个GIF在页面中只会出现一次,但是有时候在功能需求上一张相同的gif在页面可能会同时显示多张,今天我们主要介绍下页面里出现多次同一个GIF的时候可能会出现的问题及解决办法。

场景及出现的问题

一个常见的场景就是上传组件,在一些业务场景中比如同时需要用户上传多个图片且不能用同一个上传组件一次性上传多张,而是需要多个上传组件分别上传,因为它们可能不仅仅以列表的形式展现,每张上传的图片可能还需要展示对应的其他信息等,所以需要多个上传组件同时渲染在页面里;而上传组件本身会有些自定义的GIF动画来增加可交互性,比如以这个上传组件为例会有3个阶段:

  • 默认鼠标未hover进来时,就是默认的灰色静态图,
  • 鼠标hover进来时会有一个展开的动画,鼠标移开之前会固定在最后一帧
  • 鼠标离开区域后会有一个缩起来的动画,恢复到最开始的样子

比如下面这个demo里的问题:

从上图我们可以看到页面里出现了多次同一张GIF,当上面的组件鼠标移出后,又hover进下面的组件,这时下面的组件把图片切走了,但是上面那个组件的GIF也跟着动了,这个就是同一张GIF(url完全一致)展示多次可能出现的动画"联动"的问题。

问题的原因就是浏览器会把url一致的GIF当做同一张图,当要在某个地方播放动画时,其他地方的相同url的GIF也会跟着一起动(相当于只有一个动画实例),那对于这个问题我们应该如何解决呢?

解决方案

既然上面的问题是因为url一样导致的,那我们的第一个办法就是确保同一页面每次请求的url不一致:

url后面加参数

最简单粗暴的方法就是url后面加个随机数:

js 复制代码
function generateRandomUrl(url) {
  return `${url}?${Math.random()}`
}

但是这种方式如果用户移进移出太多或者pv比较大的话会导致请求很多,可能会影响CDN一直回源,我们在这基础上再优化下就是可以使用自增数,1,2,3。。。,这样的话即使是不同用户也可能拿到的是之前已有的url,而且还能保证自己页面里是唯一的,如:

js 复制代码
function createUrlGenerator() {
  let num = 0
  return (url) => {
    return `${url}?n=${++num}`
  }
}
const generateImgUrl = createUrlGenerator()
const url1 = generateImgUrl(url)
const url2 = generateImgUrl(url)

重置图片状态

一般情况下当鼠标移出区域时替换的GIF的最后一帧与最开始默认的静态图是相同的,我们也可以在hover out的时候直接把图片切换为默认静态图。当然如果最后一帧在设计上有不同的展现的话那就不能用这种方案,还是得用上面加url参数的方式。

再来看下修改后的demo,页面中同时显示多个,鼠标来回hover in/out也可以正常展示了:

总结

本文主要介绍了当页面同时多次展现同一个url的GIF图片时出现同时播放动画的问题,以及常见的解决办法,当然如果能用SVG做动画的话还是不要用GIF比较好,毕竟常规动画SVG的效果更好,而且本身是文本便于压缩,具有更好的可操控性,可以通过脚本自己去控制动画及其不同的状态等优点。

相关推荐
2501_9209317021 分钟前
React Native鸿蒙跨平台实现推箱子游戏,完成玩家移动与箱子推动,当所有箱子都被推到目标位置时,玩家获胜
javascript·react native·react.js·游戏·ecmascript·harmonyos
layman05281 小时前
webpack5 css-loader:从基础到原理
前端·css·webpack
半桔1 小时前
【前端小站】CSS 样式美学:从基础语法到界面精筑的实战宝典
前端·css·html
AI老李1 小时前
PostCSS完全指南:功能/配置/插件/SourceMap/AST/插件开发/自定义语法
前端·javascript·postcss
_OP_CHEN1 小时前
【前端开发之CSS】(一)初识 CSS:网页化妆术的终极指南,新手也能轻松拿捏页面美化!
前端·css·html·网页开发·样式表·界面美化
啊哈一半醒1 小时前
CSS 主流布局
前端·css·css布局·标准流 浮动 定位·flex grid 响应式布局
PHP武器库1 小时前
ULUI:不止于按钮和菜单,一个专注于“业务组件”的纯 CSS 框架
前端·css
方也_arkling1 小时前
Element Plus主题色定制
javascript·sass
电商API_180079052471 小时前
第三方淘宝商品详情 API 全维度调用指南:从技术对接到生产落地
java·大数据·前端·数据库·人工智能·网络爬虫
晓晓莺歌1 小时前
vue3某一个路由切换,导致所有路由页面均变成空白页
前端·vue.js