You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

iOS 11 Safari无法检测页面滚动触发jQuery懒加载函数求助

解决iOS Safari中滚动触发图片淡入脚本无效的问题

我太懂这种跨浏览器兼容的头疼了——桌面端和Chrome移动端都正常的滚动加载脚本,到了iOS Safari里连scrollStart函数都没反应,试了touch事件也没用。这其实是iOS Safari对滚动事件的特殊优化机制导致的,下面给你针对性的解决方案:

核心问题分析

iOS Safari为了提升滚动流畅度,对scroll事件做了节流处理,尤其是惯性滚动阶段,可能不会连续触发事件;另外如果touch事件没有正确设置被动监听,会被浏览器拦截;还有缓存图片不会触发onload的情况,这些都会让你的脚本彻底失效。

具体修复步骤

1. 添加防抖函数,控制事件触发频率

iOS的scrolltouchmove事件会高频触发,直接执行逻辑会导致性能问题,甚至被浏览器优化掉。用防抖函数让逻辑在滚动稳定后执行:

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滚动机制

同时绑定scrolltouchmove事件,给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中.placeholderposition: relative设置正确,图片的opacity过渡已添加-webkit-前缀(你当前的CSS已经满足要求);
  • 检查页面中是否有设置touch-action: none的元素,这类元素会阻止iOS的默认滚动行为,导致滚动事件无法触发。

这样修改后,应该就能在iOS Safari中正常触发滚动事件,实现图片的淡入加载效果了。

内容的提问来源于stack exchange,提问作者ipsomatic9

火山引擎 最新活动