JavaScriptでスクロールを扱うときのまとめ
Webページを下方向にスクロールするときに、ページがそれ以上スクロールできなくなったあと、Ajaxを使って動的に要素を追加していくというのは、TwitterやFacebookなどにも見られるように現在の主流となっています。
前回ブックマーク一覧ページがページネーションに対応したので[AutoPagerize](http://autopagerize.net)や[uAutoPagerize](https://addons.mozilla.org/ja/firefox/addon/uautopagerize/)などの拡張機能がユーザのブラウザに入っていれば、次のページを末尾に追加してくれるのですが、入っていないことや拡張機能がスマートフォンに対応していないことを想定してサイト側で対応できるようにします。
対応する中でJavaScriptでウェブサイトの高さを取得するのには色々な種類があり、どれが何を返すのか分からなくなったので備忘録としてまとめます。
まず調べた限りでWebサイトにおいて高さを取得できるのは以下のものです。
* clientHeight
* scrollHeight
* offsetHeight
* innerHeight
* outerHeight
* scrollTop
* scrollY
* screenY:
* screen.availHeight:
* screen.availTop:
* screen.height:
* pageYOffset
---
これを見るだけでもどれを使えば良いのか分からなくなりますね。
Webサイトの幅を取得するには上記の`Height`を`Width`に、`Y`を`X`に変えることで取得可能です。
今回は`window`をターゲットとしてスクロールするのを想定します。
```javascript
window.addEventListener('scroll', () => {
});
window.onscroll = () => ({
});
```
この時、`window`や`this`をとるべきなのか、`document`をとるべきなのかで分からなかったので両方で試しました。
まず`window`でとれる高さの結果は以下のとおりです。なお私はタスクバー上派なので若干変わるかもしれません。
## windowの場合
|要素 |結果|
|--------------------------|-|
|clientHeight |undefined|
|scrollHeight |undefined|
|offsetHeight |undefined|
|innerHeight |メニューバーなどを除いたブラウザの高さ|
|outerHeight |ブラウザの高さ|
|scrollTop |undefined|
|scrollY |スクロールで変動する値|
|screenY |左端を0とするディスプレイ上の座標位置|
|screen.availHeight |タスクバーを除いたディスプレイの表示領域|
|screen.availTop |タスクバー分の高さ|
|screen.height |ディスプレイの表示領域|
|pageYOffset |scrollYと同じ|
## documentの場合
次に`document`ですが、`document`はブラウザによって取得すべき要素`document.body`と`document.documentElement`の2つに別れているので`||演算子`を使って両方を取得します。
その中でどちらを先に書くかで結果が異なったので順番には気を付けましょう。
### document.bodyを先に書いた場合
|要素 |結果|
|--------------------------|---|
|clientHeight |ドキュメントの高さ|
|scrollHeight |ドキュメントの高さ|
|offsetHeight |ドキュメントの高さ|
|innerHeight |undefined|
|outerHeight |undefined|
|scrollTop |スクロールで変動する値|
|screenY |undefined|
|screen.availHeight |error|
|screen.availTop |error|
|screen.height |error|
|pageYOffset |undefined|
---
`screen`系は`window`にしかない要素のようです。
### document.documentElementを先に書いた場合
|要素 |結果|
|--------------------------|---|
|clientHeight |メニューバーなどを除いたブラウザの高さ|
|scrollHeight |ドキュメントの高さ|
|offsetHeight |ドキュメントから不明な要素分を引いた高さ(12px?)|
|innerHeight |undefined|
|outerHeight |undefined|
|scrollTop |スクロールで変動する値|
|screenY |undefined|
|screen.availHeight |error|
|screen.availTop |error|
|screen.height |error|
|pageYOffset |undefined|
---
`document.body`を先に書いた場合`clientHeight`と`offsetHeight`が`scrollHeight`と同じになってしまうのが確認できました。
## まとめ
結果としてスクロールで末尾に到達したかどうかを取得するには以下のようなコードになります。
```javascript
window.addEventListener('scroll', () => {
const el = document.documentElement || document.body;
const scrollTop = el.scrollTop;
const scrollHeight = el.scrollHeight;
const clientHeight = el.clientHeight;
if (scrollHeight - clientHeight === scrollTop) {
console.log('スクロール終了');
}
});
```
パソコンのブラウザではこれでよかったのですが、スマートフォンではスクロールしきっても必ず一致するわけではないようなので、スクロール領域の何%まで到達したかなどで判断する必要がありそうです。
const content = document.getElementById('content');
content.innerHTML = marked(content.innerHTML.replace(/>/g, '>').replace(/</g, '
関連記事