如何使用JavaScript在767px以下移动端禁用滚动淡入效果
视口宽度小于767px时禁用滚动淡入动画的实现方法
你之前调用matchMedia调试失败,核心原因是没有处理好监听的绑定/解绑逻辑,也没有适配窗口尺寸变化(比如用户旋转手机屏幕、拖动调整浏览器窗口宽度)的场景,按照下面的逻辑修改即可:
核心实现逻辑
- 用
window.matchMedia缓存媒体查询判断结果,不要在滚动回调里重复读取视口宽度触发重排 - 抽离动画启停逻辑:匹配移动端规则时直接解绑滚动监听,所有动画元素默认设为可见状态,避免内容隐藏;匹配桌面端规则时再绑定滚动监听,初始化执行一次动画检查
- 监听媒体查询状态变化,尺寸切换时自动切换动画启停状态
- 滚动事件用
requestAnimationFrame做节流,进一步降低滚动时的性能消耗,减少卡顿
修改后的完整代码
const scrollElements = document.querySelectorAll(".fade-up, .fade-in, .reveal"); // 定义移动端匹配规则:视口宽度小于767px const mobileMq = window.matchMedia('(max-width: 766px)'); let scrollTicking = false; const elementInView = (el, dividend = 1) => { const elementTop = el.getBoundingClientRect().top; return ( elementTop <= (window.innerHeight || document.documentElement.clientHeight) / dividend ); }; const elementOutofView = (el, dividend = 1) => { const elementTop = el.getBoundingClientRect().top; return ( elementTop > (window.innerHeight || document.documentElement.clientHeight) / dividend ); }; const displayScrollElement = (element) => { element.classList.add("is-visible"); }; const hideScrollElement = (element) => { element.classList.remove("is-visible"); }; const handleScrollAnimation = () => { scrollElements.forEach((el) => { if (elementInView(el, 1.05)) { displayScrollElement(el); } else if (elementOutofView(el, 1.05)) { hideScrollElement(el) } }) scrollTicking = false; } // 滚动事件节流触发 const onScroll = () => { if (!scrollTicking) { window.requestAnimationFrame(handleScrollAnimation); scrollTicking = true; } } // 切换动画启停状态 const toggleAnimationState = () => { if (mobileMq.matches) { // 移动端:解绑滚动监听,所有元素直接设为可见 window.removeEventListener("scroll", onScroll); scrollElements.forEach(el => displayScrollElement(el)); } else { // 桌面端:绑定滚动监听,执行初始检查 window.addEventListener("scroll", onScroll, { passive: true }); handleScrollAnimation(); } } // 初始化 toggleAnimationState(); // 监听视口尺寸变化,自动切换状态 mobileMq.addEventListener("change", toggleAnimationState);
额外说明
- 给滚动监听加了
passive: true参数,告诉浏览器该监听不会调用preventDefault,能进一步提升滚动性能 - 移动端场景下直接给所有元素加上
is-visible类,不会出现元素因为动画没触发被隐藏的问题 - 用
requestAnimationFrame节流后,滚动回调只会在浏览器每一帧渲染前执行一次,比原来每次滚动事件都触发的性能高很多,桌面端也能减少卡顿
不要在
handleScrollAnimation函数内部判断视口宽度,滚动时高频执行判断+读取DOM布局属性会额外增加性能开销,反而容易加剧卡顿。
内容的提问来源于stack exchange,提问作者Josh
相关产品推荐
相关产品推荐

