在线游戏开发:使用jQuery更新物品百分比时图片闪烁问题解决咨询
解决物品百分比更新时的图片闪烁问题
嘿,我看你遇到了物品百分比更新时图片闪烁的问题,这其实是因为频繁修改触发浏览器重排的样式属性(比如height),加上每次更新都同时修改CSS变量和data-value属性,导致浏览器反复重绘元素,进而出现闪烁。下面给你几个优化方向和完整的替代实现方案:
问题根源分析
你当前的实现里,:before伪元素通过height: calc(var(--value) + 20px)来控制进度高度,每次修改--value都会触发元素的重排(因为高度改变会影响布局),再加上伪元素使用了和主元素相同的背景图片,每次重排都会重新渲染背景,最终导致闪烁。
优化方案
1. 使用Transform替代Height(避免重排)
transform属于浏览器的合成层操作,不会触发重排,只会触发合成,性能更优。我们可以把伪元素的高度固定,用scaleY()配合transform-origin来实现进度效果。
2. 减少DOM操作次数
- 提前缓存DOM元素选择器,避免每次定时器回调都重新查询DOM
- 将
clearInterval的判断移到循环外,减少重复判断
3. 优化背景渲染逻辑
伪元素不再重复使用主元素的背景图片,改用纯色/渐变作为进度遮罩,或者让背景定位固定,避免重绘时重新计算背景位置。
优化后的完整代码
HTML(仅调整类名,简化内联样式)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="food_container"> <div class="food-item" data-value="0%" style="--image-url: url(https://svgur.com/i/hrP.svg);"></div> <div class="food-item" data-value="0%" style="--image-url: url(https://svgur.com/i/hrm.svg);"></div> <div class="food-item" data-value="0%" style="--image-url: url(https://svgur.com/i/hrQ.svg);"></div> </div>
CSS(核心改动:用Transform实现无闪烁进度动画)
body{ background-image: linear-gradient(to bottom, #35C10D, #6FE814); background-repeat: no-repeat; height: 100vh; font-family: 'Arial', sans-serif; margin: 0; padding: 20px; } .food_container{ display: flex; gap: 30px; } .food-item { background-image: var(--image-url); background-size: contain; background-position: center center; background-repeat: no-repeat; position: relative; height: 60px; width: 60px; } /* 百分比文本层 */ .food-item:before { content: attr(data-value); position: absolute; bottom: -20px; left: 0; right: 0; font-size: 9pt; color: #fff; text-align: center; } /* 进度遮罩层,用transform实现动画 */ .food-item:after { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-image: var(--image-url); background-size: 60px; background-position: center bottom; background-repeat: no-repeat; filter: grayscale(1) brightness(1.2); transform: scaleY(0); transform-origin: bottom center; transition: transform 0.3s ease; box-shadow: 0 -7px 22px -7px rgb(255 255 255 / 12%), 0 -7px 5px -7px white; border-top: 1px solid rgb(255 255 255 / 58%); } /* 通过CSS变量控制缩放比例 */ .food-item:after { transform: scaleY(var(--progress)); }
JavaScript(优化DOM操作,精简逻辑)
const $foodItems = $(".food-item"); // 提前缓存DOM元素,减少重复查询 let percent = 0; const countdown = setInterval(function () { percent++; // 批量更新所有元素的进度 $foodItems.each(function(index, element) { $(element) .css("--progress", percent / 100) // 用0-1的比例控制scaleY,更直观 .attr("data-value", `${percent}%`); }); // 仅判断一次,到100%清除定时器 if(percent === 100){ clearInterval(countdown); } }, 1000);
为什么这个方案能解决闪烁?
- 用
transform: scaleY()替代height修改,不会触发浏览器重排,仅触发合成层动画,性能大幅提升 - 进度层的背景定位固定,不会因为尺寸变化重新计算渲染位置
- 减少了DOM查询和重复判断的次数,降低了浏览器的工作负载
内容的提问来源于stack exchange,提问作者Morgan Codes
相关产品推荐
相关产品推荐

