レッスンに戻る

エンドレスなページ

重要性: 5

終わりのないページを作ってください。訪問者が最後までスクロールしたとき、現在の日付をテキストに自動追加します(訪問者がよりスクロールできるように)。

このようになります:

スクロールに関して2つの重要な特徴について留意してください:

  1. スクロールは “弾み” ます。 一部のブラウザ/デバイスでは、ドキュメントの開始または終了を超えてスクロールすることができます(下に空白が表示され、その後ドキュメントは自動的に通常に “戻されます”)。
  2. スクロールは精密ではありません。 ページを最後までスクロールするとき、実際には本当のドキュメントの底から 0-50px 程度離れている可能性があります。

したがって、“最後までスクロールする” とは、訪問者はドキュメントの底から 100px 以上は離れていないことを意味します。

P.S. 実践では、“より多くのメッセージ” や “より多くの商品” を表示したいです。

タスクのためのサンドボックスを開く

この解決策のコア部分は、ページの末尾にいるときに、日付情報をページに追加(もしくは、実践ではより多くのものを読み込む)する関数です。

私たちは、それをすぐに呼びだしたり、window.onscroll ハンドラとして追加することができます。

最も重要な問題は、“ページが末尾までスクロールされたかをどのようにして検出するか?” です。

ウィンドウ相対座標を使いましょう。

ドキュメントは <html> タグ、つまり document.documentElement の中に表現されます。

document.documentElement.getBoundingClientRect() でドキュメント全体のウィンドウ相対座標を得ることができます。そして、bottom プロパティはドキュメントの終わりのウィンドウ相対座標です。

例えば、HTML ドキュメント全体の高さが 2000px の場合は:

// ページのトップにいるとき
// ウィンドウ相対のトップは 0 です
document.documentElement.getBoundingClientRect().top = 0

// ウィンドウ相対の底 = 2000
// ドキュメントが長いので、おそらくウィンドウの底をはるかに超えています
document.documentElement.getBoundingClientRect().bottom = 2000

もし 500px 下にスクロールすると:

// ドキュメントトップはウィンドウより 500px 上にあります
document.documentElement.getBoundingClientRect().top = -500
// ドキュメントの底は 500px 近い
document.documentElement.getBoundingClientRect().bottom = 1500

最後までスクロールするとき、ウィンドウの高さを 600px と仮定すると:

document.documentElement.getBoundingClientRect().top = -1400
document.documentElement.getBoundingClientRect().bottom = 600

bottom は 0 にはなれないことに注意してください。なぜなら、決してウィンドウのトップには到達しないからです。底の座標の最も小さい制限はウィンドウの高さで、それ以上スクロールすることはできません。

また、ウィンドウの高さは document.documentElement.clientHeight です。

私たちは、ドキュメントの底部がそれからd 100px 以上は離れていてほしくないです。

したがって、関数は次のようになります:

function populate() {
  while(true) {
    // document bottom
    let windowRelativeBottom = document.documentElement.getBoundingClientRect().bottom;

    // もしウィンドウの高さ + 100px よりも大きい場合、ページの終わりではありません
    // (上の例の通り、大きい bottom はもっとスクロールが必要であることを意味します
    if (windowRelativeBottom > document.documentElement.clientHeight + 100) break;

    // それ以外はデータを追加する
    document.body.insertAdjacentHTML("beforeend", `<p>Date: ${new Date()}</p>`);
  }
}

サンドボックスで解答を開く