iOS 11 Safari无法检测页面滚动触发jQuery懒加载函数求助
解决iOS Safari中滚动触发图片淡入脚本无效的问题
我太懂这种跨浏览器兼容的头疼了——桌面端和Chrome移动端都正常的滚动加载脚本,到了iOS Safari里连scrollStart函数都没反应,试了touch事件也没用。这其实是iOS Safari对滚动事件的特殊优化机制导致的,下面给你针对性的解决方案:
核心问题分析
iOS Safari为了提升滚动流畅度,对scroll事件做了节流处理,尤其是惯性滚动阶段,可能不会连续触发事件;另外如果touch事件没有正确设置被动监听,会被浏览器拦截;还有缓存图片不会触发onload的情况,这些都会让你的脚本彻底失效。
具体修复步骤
1. 添加防抖函数,控制事件触发频率
iOS的scroll和touchmove事件会高频触发,直接执行逻辑会导致性能问题,甚至被浏览器优化掉。用防抖函数让逻辑在滚动稳定后执行:
function debounce(func, wait) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; }
2. 优化scrollStart函数,兼容图片缓存
iOS Safari中已缓存的图片不会触发onload事件,所以要先检查图片的complete状态,同时用requestAnimationFrame确保逻辑在浏览器重绘周期执行,避免被滚动优化忽略:
function scrollStart() { console.log("scrollStart"); requestAnimationFrame(() => { $(".placeholder").each(function (e, o) { const a = o; // 已加载的元素直接跳过,避免重复处理 if (a.classList.contains("loaded")) return; const d = a.querySelector(".img-small"); const n = new Image(); const l = new Image(); const c = $(window).scrollTop(); const s = $(a).offset().top; const t = s - c; n.src = a.dataset.large; l.src = d.src; if (t <= 720) { // 处理小图加载(兼容缓存场景) if (l.complete) { d.classList.add("loaded"); } else { l.onload = () => d.classList.add("loaded"); } // 处理大图加载(兼容缓存场景) if (n.complete) { n.classList.add("loaded"); a.classList.add("loaded"); } else { n.onload = () => { n.classList.add("loaded"); a.classList.add("loaded"); }; } a.appendChild(n); } }); }); }
3. 正确绑定事件,适配iOS Safari滚动机制
同时绑定scroll和touchmove事件,给touchmove设置被动监听避免浏览器拦截,还要在页面加载完成后主动执行一次逻辑,确保首屏可见图片正常加载:
// 对scrollStart做防抖处理,减少执行次数 const debouncedScrollStart = debounce(scrollStart, 100); // 绑定scroll事件 $(window).on('scroll', debouncedScrollStart); // 绑定touchmove事件,设置passive: true避免iOS性能警告 $(window).on('touchmove', debouncedScrollStart, { passive: true }); // 页面初始化时主动执行一次,加载首屏可见的图片 $(document).ready(() => { scrollStart(); });
额外检查点
- 确认你的CSS中
.placeholder的position: relative设置正确,图片的opacity过渡已添加-webkit-前缀(你当前的CSS已经满足要求); - 检查页面中是否有设置
touch-action: none的元素,这类元素会阻止iOS的默认滚动行为,导致滚动事件无法触发。
这样修改后,应该就能在iOS Safari中正常触发滚动事件,实现图片的淡入加载效果了。
内容的提问来源于stack exchange,提问作者ipsomatic9




