今回は、JavaScriptの.offsetHeight プロパティを使って、ページ最下部に到達した時にモーダルを表示させてみます。
カスタマイズもしやすく、コード自体も簡単な内容なので、是非チェックしてみてください。
.offsetHeight
JavaScriptの.offsetHeight は、垂直パディングや境界線を含む要素の高さを整数として返す読み取り専用のプロパティです。
// 要素を取得
var pElement = document.getElementById( "element" ) ;
// offsetHeightを取得
var offsetHeight = pElement.offsetHeight ;このプロパティは、ビジュアルなスクロールバーの厚みや子要素のマージンを無視します。要素が表示されていない場合は0を返し、高さの値はピクセル単位で表現されます。
ページ最下部に到達した時にモーダルを表示するサンプル
早速、サンプルです。
コードを設置したページの最下部にスクロールが達すると、モーダルが表示されます。
表示されたモーダルのオーバーレイか、「✖️」をクリックするとモーダルが非表示になります。
一回非表示になったモーダルは、また最下部に来ると表示されます。
実装の手順と方法
コードの詳細の前に、実装の手順と方法について解説していきます。
まずは、HTMLを記述します。
モーダルは最下部にスクロール時に表示されるので、下部の方に記述した方が良いでしょう。
<div id="myModal" class="modal">
  <div class="modal-content">
    <span class="closeBtn">×</span>
    <p>ページの最下部に到達しました</p>
  </div>
</div>次に、JavaScriptのコードを記述します。
コードは <body>〜</body>で、</body> の閉じタグ(クロージングタグ)の前に記述しましょう。
// モーダルが表示されたかどうかを判断するフラグ
var modalDisplayed = false;
// ユーザーがスクロールする度にこの関数が呼び出されます
window.onscroll = function(ev) {
    // ユーザーがページの最下部に到達したかどうかを判断します
    if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
        // ページの最下部にスクロール到達
        // モーダルが表示されていなければ、モーダルを表示します
        if (!modalDisplayed) {
            openModal();
            modalDisplayed = true;
        }
    } else {
        // ユーザーがページの最下部から上にスクロールした場合、
        // フラグをリセットして次回の最下部到達時にモーダルを再表示できるようにします
        modalDisplayed = false;
    }
};
// モーダルを表示する関数
function openModal() {
    // モーダルと閉じるボタンの要素を取得します
    var modal = document.getElementById("myModal");
    var span = document.getElementsByClassName("closeBtn")[0];
    // モーダルに"showmodal"クラスを追加して表示します
    modal.classList.add("showmodal");
    // ×ボタンがクリックされたら、モーダルから"showmodal"クラスを削除して非表示にします
    span.onclick = function() {
        modal.classList.remove("showmodal");
    }
    // モーダルの外側がクリックされたら、モーダルから"showmodal"クラスを削除して非表示にします
    window.onclick = function(event) {
        if (event.target == modal) {
            modal.classList.remove("showmodal");
        }
    }
}
最後にCSSを書きましょう。これで見た目を整えたら完了です。
.modal {
    display: block;
    position: fixed;
    z-index: 999;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    overflow: auto;
    background-color: rgba(0,0,0,0.4);
    opacity: 0;
    transition: 0.3s ease-in-out;
    pointer-events: none;
}
.modal.showmodal {
    opacity: 1;
    pointer-events: auto;
    cursor: pointer;
}
.modal-content {
    background-color: #fefefe;
    padding: 20px 25px;
    width: 90%;
    max-width: 600px;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    border-radius: 5px;
    box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.15), 0 3px 3px -2px rgba(0, 0, 0, 0.15);
    cursor: auto;
}
.modal-content p {
    margin: 0;
}
.closeBtn {
    color: #aaaaaa;
    float: right;
    font-size: 28px;
    font-weight: bold;
    line-height: 1;
    padding: 0 20px;
    position: absolute;
    right: 0;
    top: 6px;
}
.closeBtn:hover,
.closeBtn:focus {
  color: #000;
  text-decoration: none;
  cursor: pointer;
}これで完成です!
ざっくりとしたコードの解説
コードは、HTML・JavaScript・CSSの3種類です。ざっくりですが、順に解説していきます。
HTML
HTMLは、「myModal」というIDを持つ div 要素を含み、このコードで、モーダルダイアログの外枠を表しています。
<div id="myModal" class="modal">
  <div class="modal-content">
    <span class="closeBtn">×</span>
    <p>ページの最下部に到達しました</p>
  </div>
</div>そして、その中に「modal-content」のclass名を持つ子要素に、モーダルの内容(閉じるボタンとテキスト)を含んでいます。
JavaScript
JavaScriptのコードは、ページのスクロールを監視し、ユーザーがページの最下部に到達したときにモーダルを表示する機能を定義してします。
モーダル表示の状態は変数 modalDisplayed で管理され、これにより一度表示したモーダルがスクロールアップ時に非表示になり、再度最下部に到達したときにのみ表示されます。
// モーダルが表示されたかどうかを判断するフラグ
var modalDisplayed = false;
// ユーザーがスクロールする度にこの関数が呼び出されます
window.onscroll = function(ev) {
    // ユーザーがページの最下部に到達したかどうかを判断します
    if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
        // ページの最下部にスクロール到達
        // モーダルが表示されていなければ、モーダルを表示します
        if (!modalDisplayed) {
            openModal();
            modalDisplayed = true;
        }
    } else {
        // ユーザーがページの最下部から上にスクロールした場合、
        // フラグをリセットして次回の最下部到達時にモーダルを再表示できるようにします
        modalDisplayed = false;
    }
};
// モーダルを表示する関数
function openModal() {
    // モーダルと閉じるボタンの要素を取得します
    var modal = document.getElementById("myModal");
    var span = document.getElementsByClassName("closeBtn")[0];
    // モーダルに"showmodal"クラスを追加して表示します
    modal.classList.add("showmodal");
    // ×ボタンがクリックされたら、モーダルから"showmodal"クラスを削除して非表示にします
    span.onclick = function() {
        modal.classList.remove("showmodal");
    }
    // モーダルの外側がクリックされたら、モーダルから"showmodal"クラスを削除して非表示にします
    window.onclick = function(event) {
        if (event.target == modal) {
            modal.classList.remove("showmodal");
        }
    }
}
また、openModal 関数では、モーダルの表示と、モーダル外部クリックや閉じるボタンクリックによるモーダルの非表示を実装しています。
CSS
CSSは、初期状態では透明で表示されず「showmodal」のクラスが追加された時にフェードインします。モーダルのコンテンツと閉じるボタンのスタイルも指定されています。ボタンはホバーやフォーカス時に色が変わります。
.modal {
    display: block; /* モーダルをブロック要素として表示します */
    position: fixed; /* モーダルを固定位置に配置します */
    z-index: 999; /* モーダルが他の要素より前面に表示されるようにします */
    left: 0; /* モーダルを左端から0pxの位置に配置します */
    top: 0; /* モーダルを上端から0pxの位置に配置します */
    width: 100%; /* モーダルの幅を画面の全幅にします */
    height: 100%; /* モーダルの高さを画面の全高にします */
    overflow: auto; /* モーダル内のコンテンツがはみ出した場合、スクロールバーを表示します */
    background-color: rgba(0,0,0,0.4); /* モーダルの背景色を半透明の黒にします */
    opacity: 0; /* モーダルを初めて透明にします */
    transition: 0.3s ease-in-out; /* モーダルの透明度が変化する速度を指定します */
    pointer-events: none; /* モーダルにマウスイベントを無効にします(初期状態ではクリックなどが効かないようにします) */
}
.modal.showmodal {
    opacity: 1; /* モーダルを表示状態(不透明)にします */
    pointer-events: auto; /* モーダルにマウスイベントを有効にします */
    cursor: pointer; /* モーダル上のマウスカーソルをポインタにします */
}
.modal-content {
    /* モーダル内のコンテンツのスタイルを指定します */
    /* 主に背景色、パディング、位置、サイズ、枠線、影などの視覚的なプロパティを指定します */
}
.modal-content p {
    margin: 0; /* モーダル内の<p>タグのマージンを無効にします */
}
.closeBtn {
    /* 閉じるボタンのスタイルを指定します */
    /* 主に色、位置、フォントサイズ、フォントの太さなどの視覚的なプロパティを指定します */
}
.closeBtn:hover,
.closeBtn:focus {
  color: #000; /* ボタンにホバーまたはフォーカスされたときの色を黒にします */
  text-decoration: none; /* テキストの下線を削除します */
  cursor: pointer; /* マウスカーソルをポインタにします */
}
詳細はコメントアウトで記載しているので、チェックしてみてください。
さいごに
今回は、ページの最下部に到達した時にモーダルを表示させてみました。
コード自体も比較的簡単なので、カスタマイズして使ってみてください。
 
					
