别再用 wowjs 了!移动端滚动动画,使用原生 IntersectionObserver

PC 端用的好好的 AOS 库,动画也很丝滑,本来想在手机端就此延用,却出现了问题:不是不动就是不显示内容。就此又换了 WOWJS,结果还是那样,捣腾了几个小时没搞定!!!算了,还是用原生的吧。
有哪位小伙伴在手机端用了 AOS 库或者 WOW 库,而且运行正常的,麻烦告知一下解决方案!
下面将在手机端用IntersectionObserver + CSS 实现可视区动画的步骤记录下来,跟大家一起讨论讨论。
template
需要添加动的地方,要加 class 类:animate-item,fade-in-up,并且添加ref,这个ref最好有统一的开头,这样便于获取元素,比如我设置的是“animate”开头,后面加数字。
<template> <div class="page" style="min-height: 200vh;"> <!-- 1. 渐入上滑动画 --> <div class="animate-item fade-in-up" ref="animate1" data-delay="0"> ... </div> <!-- 2. 右侧滑入动画(带延迟) --> <div class="animate-item slide-in-right" ref="animate2" data-delay="200"> ... </div> </div> </template>
JS 代码实现
在目标元素进入可视区域后,会为此元素加上“animated”这个class,只有加上这个class,元素才会实现动画。

<script>
export default {
beforeDestroy() {
observer.disconnect()
},
mounted() {
// 1. 获取所有动画元素(通过 ref 前缀筛选)
const animateRefs = Object.keys(this.$refs).filter(key => key.startsWith('animate'))
const animateElements = animateRefs.map(key => this.$refs[key])
// 2. 初始化可视区检测
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
// 元素进入可视区时触发动画
if (entry.isIntersecting) {
const el = entry.target
// 获取自定义延迟(data-delay 属性)
const delay = el.dataset.delay || 0
// 延迟执行动画(模拟 wowjs 的 delay 效果)
setTimeout(() => {
el.classList.add('animated')
}, delay)
// 只触发一次动画
observer.unobserve(el)
}
})
}, {
threshold: 0.1, // 元素进入可视区 10% 就触发(可调整)
rootMargin: '0px 0px -50px 0px' // 底部偏移 50px,提前触发(适配移动端)
})
// 3. 监听所有动画元素
animateElements.forEach(el => {
// 兼容 v-for 生成的数组 refs
if (Array.isArray(el)) {
el.forEach(item => observer.observe(item))
} else {
observer.observe(el)
}
})
}
}
</script>
如果动画元素在自定义滚动容器(如 div 滚动)内,只需修改IntersectionObserver的root参数:
// 获取自定义滚动容器
const scrollContainer = this.$refs.scrollWrapper
// 初始化 observer 时指定 root
const observer = new IntersectionObserver((entries) => {
// 逻辑不变
}, {
root: scrollContainer, // 指定自定义滚动容器为检测根节点
threshold: 0.1,
rootMargin: '0px 0px -50px 0px'
})
style 样式扩展
如果想要更多动画,可以自行扩展。
/* 动画 */
.animate-item {
opacity: 0; /* 初始隐藏 */
transition: all 0.6s ease-out; /* 统一动画时长+缓动 */
/* 移动端适配:避免布局塌陷 */
min-height: 44px;
margin: 20px 0;
}
/* 动画触发后状态 */
.animate-item.animated {
opacity: 1;
transform: translate(0);
}
/* 1. 渐入上滑动画 */
.fade-in-up {
transform: translateY(30px); /* 初始向下偏移 30px */
}
/* 2. 右侧滑入动画 */
.slide-in-right {
transform: translateX(30px); /* 初始向右偏移 30px */
}
/* 3. 缩放动画 */
.zoom-in {
transform: scale(0.9); /* 初始缩小到 90% */
}
/* 4. 左侧滑入动画(横向滚动容器用) */
.slide-in-left {
transform: translateX(-20px); /* 初始向左偏移 20px */
}
以上代码可以直接拿去用。
IntersectionObserver 是什么
IntersectionObserver是浏览器原生提供的可视区检测 API,翻译过来叫「交叉观察器」—— 它能 “盯着” 某个元素,当元素和指定的「可视区域」(比如浏览器窗口、自定义滚动容器)发生 “交叉”(也就是元素进入 / 离开可视区)时,自动触发你设定的回调函数。
与第三方库的区别:
- 传统方式(比如 wowjs 用的):监听
scroll事件 + 手动计算getBoundingClientRect(),滚动一次就计算一次,性能差、移动端还容易出错; - IntersectionObserver:浏览器底层帮你监控,元素进入 / 离开可视区时才触发回调,零性能损耗、检测精准、移动端全兼容。
核心语法:
// 1. 创建观察器实例
const observer = new IntersectionObserver(
// 回调函数:元素可视区状态变化时触发
(entries) => {
entries.forEach(entry => {
// entry.isIntersecting:布尔值,true=元素进入可视区,false=离开
if (entry.isIntersecting) {
// 做你想做的事:触发动画、加载图片、统计曝光等
entry.target.classList.add('animated')
// 只观察一次:触发后停止监控该元素(避免重复触发)
observer.unobserve(entry.target)
}
})
},
// 配置项(可选,核心参数)
{
root: null, // 监听的根容器,默认是 window(浏览器可视区);自定义容器传 DOM 元素
threshold: 0.1, // 触发阈值:元素进入可视区 10%时触发(0=刚进就触发,1=完全进入才触发)
rootMargin: '0px 0px -50px 0px' // 可视区偏移:底部多算 50px,提前触发(适配移动端)
}
)
// 2. 开始观察指定元素
observer.observe(document.querySelector('.animate-item'))
// 3. 停止观察(可选)
// observer.unobserve(元素)
// 4. 销毁观察器(组件卸载时用)
// observer.disconnect()
核心配置:

记住 3 个核心操作:创建实例new IntersectionObserver() → 观察元素observe() → 触发后停止unobserve()。
以上关于别再用 wowjs 了!移动端滚动动画,使用原生 IntersectionObserver的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » 别再用 wowjs 了!移动端滚动动画,使用原生 IntersectionObserver
微信
支付宝