You need to enable JavaScript to run this app. 如何在完全动态加载的页面中监听类似document.readyState的事件?
优惠活动
大模型
产品
解决方案
定价
更多

如何在完全动态加载的页面中监听类似document.readyState的事件?

动态加载页面资源加载完成监听方案

document.readyState仅对应整页初始加载的状态,动态插入DOM后的资源加载不会触发该状态更新,也不会触发全局readystatechange事件,因此需要手动统计插入内容的资源加载情况,以下是两种可落地的实现方案:


方案1:预加载资源后再插入DOM(体验最优)

该方案会先预加载所有需要用到的资源,全部加载完成后再把页面内容插入到DOM中,用户不会看到资源逐步加载的闪烁过程,完全符合你的需求。

实现步骤

  • 拿到AJAX返回的页面HTML后,先通过临时DOM节点提取所有资源地址,包括图片的src、srcset,视频的src、封面图,资源地址需要去重避免重复加载
  • 逐个创建资源实例预加载,统计总资源数和已加载完成(含加载失败)的数量
  • 所有资源加载完成后,再插入页面内容、隐藏加载屏,同地址资源浏览器会直接读取缓存,不会重复发起请求

示例代码

$.ajax({
  url: '你的子页面接口地址',
  type: 'GET',
  beforeSend: function() {
    // 显示加载屏
    $('.loading-screen').show();
  },
  success: function(res) {
    // res中pageContent为页面HTML,otherData为你需要的额外业务数据
    const { pageContent, otherData } = res;
    // 临时DOM用于提取资源
    const tempDom = document.createElement('div');
    tempDom.innerHTML = pageContent;
    
    // 收集所有需要预加载的资源
    const resources = [];
    // 收集图片资源
    tempDom.querySelectorAll('img').forEach(img => {
      img.src && resources.push(img.src);
      img.srcset && resources.push(...img.srcset.split(',').map(item => item.trim().split(' ')[0]));
    });
    // 收集视频相关资源
    tempDom.querySelectorAll('video').forEach(video => {
      video.src && resources.push(video.src);
      video.poster && resources.push(video.poster);
    });
    tempDom.querySelectorAll('video source').forEach(source => {
      source.src && resources.push(source.src);
    });
    // 资源去重
    const uniqueResources = [...new Set(resources)];
    let loadedCount = 0;
    const totalCount = uniqueResources.length;

    // 兜底:没有资源直接完成
    if (totalCount === 0) {
      insertPageContent(pageContent);
      return;
    }

    // 超时兜底:避免资源加载失败导致加载屏永远显示
    const loadTimeout = setTimeout(() => {
      insertPageContent(pageContent);
    }, 3000); // 可自行调整最长等待时间

    // 逐个预加载资源
    uniqueResources.forEach(url => {
      const isImage = /\.(png|jpg|jpeg|gif|webp|svg)$/i.test(url);
      const isVideo = /\.(mp4|webm|ogg)$/i.test(url);
      let loadElement;

      if (isImage) {
        loadElement = new Image();
      } else if (isVideo) {
        loadElement = document.createElement('video');
        loadElement.preload = 'auto';
      } else {
        // 其他类型资源用fetch预加载
        fetch(url).then(handleLoad, handleLoad);
        return;
      }

      loadElement.onload = handleLoad;
      loadElement.onerror = handleLoad; // 加载失败也计数,不阻塞流程
      loadElement.src = url;
    });

    function handleLoad() {
      loadedCount++;
      if (loadedCount === totalCount) {
        clearTimeout(loadTimeout);
        insertPageContent(pageContent);
      }
    }

    function insertPageContent(content) {
      // 插入页面内容
      $('#page-container').html(content);
      // 隐藏加载屏
      $('.loading-screen').hide();
      // 执行history.push、其他业务逻辑
      // ...
    }
  }
});

方案2:先插入DOM再监听资源加载

如果你的页面资源体积过大,不想让用户长时间等待白屏,可以先把页面内容插入DOM,再监听容器内所有资源的加载事件,加载完成后再隐藏加载屏,实现逻辑和方案1基本一致,仅调整插入DOM的时机即可。


可选优化

可以通过loadedCount / totalCount计算加载进度,在加载屏上展示进度百分比,进一步提升用户体验。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.16 16:06:09