乐趣区

关于javascript:如何知道-window-的-load-事件已经触发

背景

为了使页面加载更快,经常将一些不重要的第三方脚本在页面实现加载后进行懒加载。

// 做一些不影响业务的事件
window.addEventListener('load', () => {
  // 懒加载埋点剖析
  loadScript({
    url: 'https://www.domain.com/test.js',
    timeout: 10000
  }).then(() => {console.log('ok');
  }).catch(console.error);
  // 其余
  // ...
});

因为 load 事件只会触发一次,如果在懒加载(load)的脚本中又有懒加载的脚本,就会导致内嵌的脚本无奈触发。

// 做一些不影响业务的事件
window.addEventListener('load', () => {window.addEventListener('load', () => {
    // 不能执行了
    console.log('我无了');
  });
});

解决方案

在 HTML 中 document.readyState 属性能够反馈以后页面的加载状态。

  • uninitialized – Has not started loading yet
  • loading – Is loading
  • loaded – Has been loaded
  • interactive – Has loaded enough and the user can interact with it
  • complete – Fully loaded

如果属性为 complete 则可认为以后页面曾经加载实现。

/**
 * 加载实现
 * @param timeout {Number} 超时工夫 / 单位:秒
 * @return {Promise<Boolean>} document is loaded? 
*/
function windowLoaded(timeout = 90) {
    let loaded, loadFail;
    const status = new Promise((resolve, reject) => {
        loaded = resolve;
        loadFail = reject;
    });
    if (document.readyState === 'complete') {loaded('complete');
    } else {window.addEventListener('load', () => loaded('load'));
    }
    // 超过 timeout 秒后加载失败
    setTimeout(() => loadFail('timeout'), timeout * 1000);
    return status;
}

// load
windowLoaded()
  .then(res => {console.log(res);
  })
  .catch(console.error);

参考

HTML DOM readyState Property
What is the non-jQuery equivalent of ‘$(document).ready()’?
PerformanceTiming.loadEventEnd
Window: load event

版权申明

本博客所有的原创文章,作者皆保留版权。转载必须蕴含本申明,放弃本文残缺,并以超链接模式注明作者后除和本文原始地址:https://blog.mazey.net/1994.html

退出移动版