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

相关推荐
崔庆才丨静觅7 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60618 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了8 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅8 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅8 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅9 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment9 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅9 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊9 小时前
jwt介绍
前端
爱敲代码的小鱼9 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax