一个页面里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的效果更好,而且本身是文本便于压缩,具有更好的可操控性,可以通过脚本自己去控制动画及其不同的状态等优点。

相关推荐
m0_748240251 小时前
前端如何检测用户登录状态是否过期
前端
black^sugar1 小时前
纯前端实现更新检测
开发语言·前端·javascript
寻找沙漠的人1 小时前
前端知识补充—CSS
前端·css
GISer_Jing2 小时前
2025前端面试热门题目——计算机网络篇
前端·计算机网络·面试
m0_748245522 小时前
吉利前端、AI面试
前端·面试·职场和发展
理想不理想v2 小时前
webpack最基础的配置
前端·webpack·node.js
pubuzhixing2 小时前
开源白板新方案:Plait 同时支持 Angular 和 React 啦!
前端·开源·github
2401_857600952 小时前
SSM 与 Vue 共筑电脑测评系统:精准洞察电脑世界
前端·javascript·vue.js
2401_857600952 小时前
数字时代的医疗挂号变革:SSM+Vue 系统设计与实现之道
前端·javascript·vue.js
GDAL2 小时前
vue入门教程:组件透传 Attributes
前端·javascript·vue.js