EagleLand

2020.08.04

DOMContentLoaded イベントや load イベントを約束する Promise オブジェクト

documentDOMContentLoaded イベントwindowload イベント は Web 開発者にとってお馴染みのブラウザライフサイクルである。

結論から言うと、これらを簡単にハンドリングするための html-ready という小さなライブラリを作ったという話。実装自体はとても簡単で、ここで改めて説明するほどのものではない。ただ、同じことを色んな場面で何度も何度も書いている実感があり、巷にも期待する機能を持ったライブラリがなかったので作った。

イベントのタイミングとハンドリング方法

簡単におさらいすると、それぞれ以下のような条件で発火する。

これらのタイミングを取得するためには、以下のように addEventListener を使ってコールバック内に任意の処理を記述すれば良い。

document.addEventListener('DOMContentLoaded', () => {
  console.log('DOMContentLoaded is fired');
});

window.addEventListener('load', () => {
  console.log('load is fired');
});

ただし、これらはイベントが発火されたあとに実行されるとコールバックが実行されないので、より丁寧にハンドリングしようとすると document.readyState を参照して HTML ドキュメントの読み込み状態をチェックしなくてはならない。

if (document.readyState === 'interactive' || document.readyState === 'complete') {
  console.log('DOMContentLoaded is already fired');
} else {
  document.addEventListener('DOMContentLoaded', () => {
    console.log('DOMContentLoaded is fired');
  });
}

if (document.readyState === 'complete') {
  console.log('load is already fired');
} else {
  window.addEventListener('load', () => {
    console.log('load is fired');
  });
}

html-ready を使って Promise で待機する方法

html-readydocumentReady オブジェクトと windowReady オブジェクトが含まれており、これらを使うと以下のように記述できる。

import { documentReady, windowReady } from 'https://unpkg.com/html-ready';

documentReady.then(() => {
  console.log('DOMContentLoaded is fired');
});

windowReady.then(() => {
  console.log('load is fired');
});

これは unpkg を直接参照して ESM でロードしている例だが、もちろん npm install html-ready を実行してモジュールバンドラに依存関係を解決させることも可能である。