Home Code About

モーダル + youtube再生

ボタン

youtubeのAPIとMicromodalを使用して実装しています。
こちらも実案件で使用したものです。
同ページ内に複数設置されても問題なく動作するように気をつけて実装しました。

<div id="modal" aria-hidden="true" class="c-modal">

    <!-- overlay -->
    <div class="c-modal__overlay" tabindex="-1" data-micromodal-close>
        <div class="c-modal__inner">

            <!-- container -->
            <div role="dialog" aria-modal="true" aria-label="動画再生" class="c-modal__container">
                <div class="c-modal__movie">
                    <div id="js-modal-target"></div>
                </div>
            </div>
        </div>
    </div>
</div>
<a href="" class="c-modal__btn js-modal-trigger" data-micromodal-trigger="modal" target="_blank" data-movie-id="tEaFAp4862s">ボタン</a>
<!-- [/c-modal] -->
.c-modal {
  display: none;
}

.c-modal.is-open {
  display: block;
}

.c-modal[aria-hidden=true] {
  display: none;
}

.c-modal__overlay {
  position: fixed;
  inset: 0;
  z-index: 99;
}

.c-modal__inner {
  display: grid;
  place-items: center;
  height: 100%;
  background: rgba(0, 0, 0, 0.5);
}

.c-modal__container {
  position: relative;
  max-height: 100svh;
  aspect-ratio: 16/9;
  padding: 1rem;
  border-radius: 10px;
  background-color: white;
}
document.addEventListener('DOMContentLoaded', () => {
    'use strict';

    // YouTube IFrame Player API
    const tag = document.createElement('script');
    tag.src = 'https://www.youtube.com/iframe_api';
    const firstScriptTag = document.getElementsByTagName('script')[0];
    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
    let player;

    const triggers = document.querySelectorAll('.js-modal-trigger');
    const isTouchDevice = window.matchMedia(
        '(hover: none) and (pointer: coarse)'
    ).matches;

    if (isTouchDevice) {
        for (const trigger of triggers) {
            const movieId = trigger.dataset.movieId;
            const youtubeUrl = 'https://www.youtube.com/watch?v=' + movieId;
            trigger.href = youtubeUrl;
        }
    } else {
        let movieId;

        for (const trigger of triggers) {
            trigger.addEventListener('click', (e) => {
                e.preventDefault();
                movieId = trigger.dataset.movieId;
            });
        }

        window.onYouTubeIframeAPIReady = () => {
            MicroModal.init({
                openClass: 'is-open',
                awaitOpenAnimation: true,
                awaitCloseAnimation: true,
                disableScroll: true,
                disableFocus: true,
                onShow: () => {
                    player = new YT.Player('js-modal-target', {
                        playerlets: {
                            playsinline: 1, //iOSでインライン再生
                            controls: 1, // コントロールバー非表示
                            fs: 0, //全画面表示ボタン非表示
                            enablejsapi: 1, //JavaScript API有効
                            modestbranding: 1, //youtubeロゴ非表示
                            iv_load_policy: 3, //動画アノテーション非表示
                            disablekb: 1 //キーボード操作無効
                        },
                        videoId: movieId,
                        events: {
                            onReady: () => {
                                player?.playVideo();
                            }
                        }
                    });
                },
                onClose: () => {
                    player?.destroy();
                }
            });
        };
    }
});