初投稿です。
駆け出しのエンジニアではありますが、質問やご意見等が御座いましたらお気軽にどうぞ。
##概要
サイト制作をしていると、
スクロール時に追従してくるボタンなんかをよく実装すると思います。
ですがデザイン上、フッター等の背景色とボタンの色が被ってしまうこともあるでしょう。
今回はトップに戻るボタンを、footer等の要素手前辺りで停止させるのに色々試した結果、
Javascriptでの制御がとても解りやすかったので備忘録的に残しておきます。
##制御部分のコード
window.addEventListener('scroll', () => {
const elem = '任意のボタン positionはfixedで右下に設定';
const docHeight = document.body.clientHeight;
const scrollCount = document.documentElement.scrollTop || document.body.scrollTop;
const scrollPos = document.documentElement.clientHeight + scrollCount;
const footerHeight = document.querySelector('footer(任意)').clientHeight;
if (docHeight - scrollPos <= footerHeight) {
elem.style.position = 'absolute';
elem.style.bottom = footerHeight + 20 + 'px';
} else {
elem.style.position = 'fixed';
elem.style.bottom = 20 + 'px';
}
});
##下準備として
ボタン部分はHTML/CSSで任意に作成しfixedで追従しておきます。
また、JSのイベント時にはabsoluteに切り替えますので、body下に親要素のrelativeを設定しておく必要があります。
##部分的に解説
###定数に格納
//ページ全体の高さ取得
const docHeight = document.body.clientHeight;
//対応ブラウザ別に縦のスクロール量取得
const scrollCount = document.documentElement.scrollTop || document.body.scrollTop;
//ページの表示領域を取得し、スクロール量を足す
const scrollPos = document.documentElement.clientHeight + scrollCount;
//この場合はfooterの高さを指定
const footerHeight = document.querySelector('footer(任意)').clientHeight;
スクロールイベントに必要なそれぞれの値を取得し、定数に格納します。
ブラウザによる違いや、スクロールバーを含むか含まないか等少しややこしいですが、
それぞれ意味が異なってきますので注意。
###イベントの処理
if (docHeight - scrollPos <= footerHeight) {
elem.style.position = 'absolute';
elem.style.bottom = footerHeight + 20 + 'px';
} else {
elem.style.position = 'fixed';
elem.style.bottom = 20 + 'px';
}
scrollCountによりscrollPosの値はスクロールとともに増えていきます。
ページ全体の高さがfooterの高さ以下になった時、
fixedからabsoluteに切り替わります。
位置設定はfooterの高さより20pxほどマージンを取るように設定しているだけなので、
デザインによりけりとなります。
範囲外では元に戻すように設定しております。
これで違和感なく切り替わります。