IntersectionObserverでモーダルを表示する方法[JavaScript]

IntersectionObserverでモーダルを表示させてみる

素のJavaScript(Vanilla JS) で、特定の位置をすぎたらモーダルを表示させてみます

この記事は、素のjavaScriptで(jQuery等を使わずに)
特定の位置をすぎたら」を条件に、モーダルを表示させてみる方法を書いた記事です。

以前の記事同様、今回も使用するのは
IntersectionObserver です。
(この IntersectionObserver は、lazyloadと組み合わせるケースなどにおいてGoogleも使用を推奨しており、今後、一般的に使われていく方法になると思われます。)

↑こちらの動画をご覧ください。画面をスクロールして、指定した要素がViewport内に入ったタイミングを「IntersectionObserver」で監視・判定。モーダルを表示しています。

それでは次のセクションで、上記の動画のような仕組みを実装するための、html, js, css それぞれのコードを書いていきます。

html, js, css の各コードをご紹介

[html]

<div class="target-container is-target">
  <div class="target-item">
    <h2>モーダル表示させる基準の要素</h2>
    ここまでスクロールしたら、モーダル表示させる基準の要素
  </div>
</div>

<div class="target-modal">
  <h3>モーダルのタイトル</h3>
  <button class="target-modal-button-close">閉じる</button>
  <p class="target-modal-container-thumbnail"><img class="target-modal-thumbnail" src="https://picsum.photos/id/790/600" alt="サムネイル"></p>
  <p class="target-modal-container-text">いつもご覧いただきありがとうございます。<br />2021年も残すところあと3週間と少しですね。</p>
</div>

<div class="target-modal-bg"></div>

[css]

.target-container {
  margin: 1200px auto 1200px;
  width: max(264px, min(calc(100vw - 8px), 1200px));
}
.target-modal-bg {
  background: rgba(0, 0, 0, 0.3);
  display: block;
  height: 100%;
  left: 0;
  opacity: 0;
  position: fixed;
  top: 0;
  transition: opacity .7s;
  width: 100%;
}
.target-modal {
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  height: auto;
  left: 50%;
  opacity: 0;
  padding: 2rem;
  position: fixed;
  text-align: center;
  top: 45%;
  transform: translate(-50%, -50%);
  transition: opacity, top .7s;
  width: max(300px, min(calc(100vw - 8px), 40vw));
}
.target-modal-container-thumbnail {
  margin: 2rem auto;
}
.target-modal-thumbnail {
  border-radius: 50%;
  height: 200px;
  width: 200px;
}
.target-modal-container-text {
  font-size: .875rem;
  line-height: 1.75;
}
.target-modal-button-close {
  background: none;
  border: none;
  cursor: pointer;
  font-size: .75rem;
  top: .625rem;
  transition: opacity .3s;
  position: absolute;
  right: .625rem;
}
.target-modal-button-close:hover {
  opacity: 0.7;
}
.target-modal.is-show {
  top: 50%;
}
.target-modal.is-show,
.target-modal-bg.is-show {
  opacity: 1;
}

[JavaScript]

<script>
const myTarget = document.querySelector('.is-target');
const myModal = document.querySelector('.target-modal');
const myModalbg = document.querySelector('.target-modal-bg');
const myButtonClose = document.querySelector('.target-modal-button-close');
    
// makeObserver(); の実行(関数名は何でも良いです)
makeObserver();

// IntersectionObserverを作成する関数
function makeObserver() {
let myObserver;

// IntersectionObserverのオプション設定
let myOptions = {
  root: null,
  rootMargin: '0px 0px',
  threshold: '0'
};
      
myObserver = new IntersectionObserver(myIntersect, myOptions);

myObserver.observe(myTarget);
}

function myIntersect(entries, myObserver) {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      myModal.classList.add('is-show');
      myModalbg.classList.add('is-show');
    }
  });
}

myModalbg.addEventListener('click', () => {
  myModal.classList.remove('is-show');
  myModalbg.classList.remove('is-show');
});

myButtonClose.addEventListener('click', () => {
  myModal.classList.remove('is-show');
  myModalbg.classList.remove('is-show');
});
</script>

↑以上の記述で、冒頭の動画のようなモーダル表示が可能です。

この記事のまとめ

今回は、IntersectionObserverを使ってモーダルを表示する方法について、ご紹介しました。

冒頭に書いた通り、lazyload と組み合わせるケースなどにおいて
Googleが公開している記事内でも使用を推奨している手法です。
仕組みを覚えておくと、なにかと使えるかと思います。

※この記事は、内容の品質向上を目的に、随時更新を行う場合があります。