
本文介绍如何通过监听鼠标滚轮事件,结合 css 样式动态控制图片位置与可见性,实现类似 publicofficial.co 网站的滚动视差/渐显动画效果,兼容移动端,无需依赖第三方库。
本文介绍如何通过监听鼠标滚轮事件,结合 css 样式动态控制图片位置与可见性,实现类似 publicofficial.co 网站的滚动视差/渐显动画效果,兼容移动端,无需依赖第三方库。
要实现“随滚动渐显图片”的视觉效果(常被称为 scroll-triggered reveal 或 scroll-linked animation),核心思路并非依赖传统 scroll 事件(易触发频繁、性能不佳),而是利用更轻量、高响应的 wheel 事件配合元素的可视状态判断与 CSS 过渡控制。
✅ 推荐实现方案:IntersectionObserver + CSS 动画(现代、高效、移动端友好)
虽然原始回答提到了 wheel 事件监听,但该方式需手动计算偏移、易引发布局抖动,且难以精准控制“进入视口时才触发”,不推荐作为首选方案。当前最佳实践是使用原生 IntersectionObserver API:
<!-- HTML:为每张图片添加统一 class --> <img src="photo1.jpg" alt="示例图" class="fade-in-image"><img src="photo2.jpg" alt="示例图" class="fade-in-image">
/* CSS:默认隐藏 + 过渡效果 */
.fade-in-image {
opacity: 0;
transform: translateY(30px);
transition: opacity 0.6s ease-out, transform 0.6s ease-out;
}
.fade-in-image.visible {
opacity: 1;
transform: translateY(0);
}
// JavaScript:使用 IntersectionObserver 监听进入视口
const observer = new IntersectionObserver(
(entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
}
});
},
{
threshold: 0.1 // 当 10% 图片进入视口即触发
}
);
// 观察所有带 .fade-in-image 的元素
document.querySelectorAll('.fade-in-image').forEach(img => {
observer.observe(img);
});
⚠️ 注意事项与优化建议
- 移动端兼容性:IntersectionObserver 在 iOS Safari 12.2+ 和 Android Chrome 51+ 均已原生支持,可放心使用;如需兼容更低版本,可用 intersection-observer-polyfill。
- 性能优先:避免在 wheel 或 scroll 中直接修改 style.top/left——这会强制同步重排(layout thrashing)。IntersectionObserver 是异步、被动监听,零性能损耗。
-
图片懒加载协同:可将 loading="lazy" 与渐显逻辑结合,进一步提升首屏加载速度:
<img src="photo.jpg" loading="lazy" class="fade-in-image">
- 自定义动效:可通过 data-animation 属性区分入场方向(如 data-animation="slide-up" / "fade-scale"),配合 CSS 自定义属性动态应用不同 transition。
✅ 总结
实现滚动触发动画图片,不应依赖 wheel 事件手动位移,而应采用语义清晰、性能卓越、移动端开箱即用的 IntersectionObserver 方案。它天然适配触摸滚动(包括 iOS 弹性滚动)、支持阈值控制、无需监听页面尺寸变化,是构建专业级滚动动画的现代标准解法。只需 10 行核心 JS + 简洁 CSS,即可获得媲美 publicofficial.co 的流畅渐显体验。











