はじめに
動画のサムネイル画像をクリックしてモーダルウィンドウを表示し、その中にYouTube動画を動的に埋め込む方法について説明します。なお、本記事ではYouTube動画を動的に埋め込むまでを範囲とし、埋め込んだ動画の再生制御などは範囲外とします。
実装
サンプル
ふたつのサムネイル画像をそれぞれクリックしてみてください。フルスクリーンのモーダルウィンドウが表示され、その中にそれぞれに対応したYouTube動画が埋め込まれています。モーダルウィンドウの動画以外の場所をクリックするとモーダルウィンドウが閉じます。
ソースコードはGistで公開しています。
HTML
コンテナーの中に動画のサムネイル画像を並べます。各動画のdata-url
属性で動画のURLを持たせます。
HTML
<div class="container">
<div class="js-modal-video-open" data-url="https://www.youtube.com/watch?v=xxxxxxxxxxx">
<img class="thumbnail" src="x-thumb.jpg" />
</div>
<div class="js-modal-video-open" data-url="https://www.youtube.com/watch?v=yyyyyyyyyyy">
<img class="thumbnail" src="y-thumb.jpg" />
</div>
<div id="modal-video" class="close js-modal-video-close">
<div id="player"></div>
</div>
</div>
Gistはこちら。
Slim
.container
.js-modal-video-open[data-url="https://www.youtube.com/watch?v=xxxxxxxxxxx"]
img.thumbnail[src="x-thumb.jpg"]
.js-modal-video-open[data-url="https://www.youtube.com/watch?v=yyyyyyyyyyy"]
img.thumbnail[src="y-thumb.jpg"]
#modal-video.close.js-modal-video-close
#player
Gistはこちら。
CSS
まずはCSSの全文を掲載します。
SCSS
.container {
display: flex;
.thumbnail {
cursor: pointer;
width: 320px;
height: 180px;
margin: 0 8px;
}
#modal-video {
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
position: fixed;
z-index: 8;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: rgba(#000,.75);
transition: .5s;
&.close {
filter: opacity(0);
visibility: hidden;
}
&.open {
filter: opacity(1);
visibility: visible;
}
iframe {
width: 64vw;
height: 36vw;
}
}
}
Gistはこちら。
ひとつひとつ分解して説明していきます。
SCSS
.thumbnail {
cursor: pointer;
width: 320px;
height: 180px;
margin: 0 8px;
}
サムネイル画像に適用させるスタイルです。カーソルをポインターにしてクリック可能であることを示します。
SCSS
#modal-video {
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
position: fixed;
z-index: 8;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: rgba(#000,.75);
transition: .5s;
&.close {
filter: opacity(0);
visibility: hidden;
}
&.open {
filter: opacity(1);
visibility: visible;
}
iframe {
width: 64vw;
height: 36vw;
}
}
モーダルウィンドウのスタイルです。初期状態はclose
クラスを適用させて不可視状態にしておき、後述するJavaScriptの処理でopen
を適用させ可視状態に変化します。iframe
タグはそのままYouTube動画のスタイルです。後述するJavaScriptの処理でもサイズ指定することはできますが、動画サイズをレスポンシブに変化させたい場合はCSSで設定する必要があります。
JavaScript
まずはJavaScriptの全文を掲載します。
JavaScript
/**
* @class ToggleModal
* @description モーダルウィンドウの表示切替を行い、YouTube動画を動的に埋め込む
* @argument target 対象のYouTube動画を含む要素
*/
class ToggleModal {
constructor(target) {
this.target = target;
this.videoId = target.dataset.url.slice(-11);
this.loadIframePlayerAPI();
this.open();
this.close();
}
/**
* @method loadIframePlayerAPI
* @description IFrame Player APIを読み込む
*/
loadIframePlayerAPI() {
const tag = document.createElement('script');
tag.src = 'https://www.youtube.com/iframe_api';
const firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
}
/**
* @method onYouTubeIframeAPIReady
* @description YouTube動画を動的に埋め込む
*/
onYouTubeIframeAPIReady() {
let ytPlayer = new YT.Player('player', {
videoId: this.videoId,
playerVars: {
'autoplay': 1,
'controls': 1
}
});
}
/**
* @method remakePlayerElement
* @description YouTube動画を埋め込む要素を再作成
*/
remakePlayerElement() {
const modal = document.querySelector('#modal-video');
modal.removeChild(modal.firstElementChild);
let tag = document.createElement('div');
tag.id = 'player';
modal.appendChild(tag);
}
/**
* @method open
* @description モーダルウィンドウを開く
*/
open() {
this.target.addEventListener('click', event => {
this.onYouTubeIframeAPIReady();
document.querySelector('#modal-video').classList.add('open');
document.querySelector('#modal-video').classList.remove('close');
});
}
/**
* @method close
* @description モーダルウィンドウを閉じる
*/
close() {
document.querySelector('.js-modal-video-close').addEventListener('click', event => {
document.querySelector('#modal-video').classList.add('close');
document.querySelector('#modal-video').classList.remove('open');
this.remakePlayerElement();
});
}
}
document.addEventListener('DOMContentLoaded', event => {
document.querySelectorAll('.js-modal-video-open').forEach(element => {
new ToggleModal(element);
});
});
Gistはこちら。
ひとつひとつ分解して説明していきます。
JavaScript
/**
* @class ToggleModal
* @description モーダルウィンドウの表示切替を行い、YouTube動画を動的に埋め込む
* @argument target 対象のYouTube動画を含む要素
*/
class ToggleModal {
constructor(target) {
this.target = target;
this.videoId = target.dataset.url.slice(-11);
this.loadIframePlayerAPI();
this.open();
this.close();
}
}
ToggleModal
クラスのコンストラクターでは、対象のYouTube動画を含む要素から動画のURLを取得し、YouTube動画の埋め込みを可能にするIFrame Player APIの読み込みとモーダルウィンドウの開閉イベントのリスナー登録を行います。
JavaScript
/**
* @method loadIframePlayerAPI
* @description IFrame Player APIを読み込む
*/
loadIframePlayerAPI() {
const tag = document.createElement('script');
tag.src = 'https://www.youtube.com/iframe_api';
const firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
}
IFrame Player APIの読み込みを行います。ドキュメントに含まれる最初のscript
タグの前にIFrame Player API用のscript
タグを追加します。
JavaScript
/**
* @method open
* @description モーダルウィンドウを開く
*/
open() {
this.target.addEventListener('click', event => {
this.onYouTubeIframeAPIReady();
document.querySelector('#modal-video').classList.add('open');
document.querySelector('#modal-video').classList.remove('close');
});
}
/**
* @method close
* @description モーダルウィンドウを閉じる
*/
close() {
document.querySelector('.js-modal-video-close').addEventListener('click', event => {
document.querySelector('#modal-video').classList.add('close');
document.querySelector('#modal-video').classList.remove('open');
this.remakePlayerElement();
});
}
モーダルウィンドウの開閉イベントのリスナー登録を行います。モーダルウィンドウを開く前にYouTube動画を埋め込む処理を行い、モーダルウィンドウを閉じた後にYouTube動画を埋め込む要素を再作成します。
JavaScript
/**
* @method onYouTubeIframeAPIReady
* @description YouTube動画を動的に埋め込む
*/
onYouTubeIframeAPIReady() {
let ytPlayer = new YT.Player('player', {
videoId: this.videoId,
playerVars: {
'autoplay': 1,
'controls': 1
}
});
}
IFrame Player APIを使ってYouTube動画を埋め込みます。YT.Player
クラスの第1引数(今回はplayer
)は埋め込むYouTube動画のIDを指定します。指定したIDの子要素にYouTube動画が追加されるのではなく、指定したIDの要素そのものがYouTube動画になります。つまり、指定したIDの要素はなくなるということです。
YT.Player
クラスの第2引数のハッシュは再生プレイヤーのパラメーターを設定します。
パラメーター | 説明 |
---|---|
videoId |
埋め込むYouTube動画のIDを指定(必須)。 |
playerVars: { autoplay } |
動画を開いたときに自動再生しない場合は0 、自動再生する場合(iOSを除く)は1 を指定。 |
playerVars: { controls } |
再生プレイヤーのコントローラー(音量やシークバーなど)を表示しない場合は0 、表示する場合は1 を指定。 |
設定できるパラメーターについて詳しくは以下の記事を参照してください。
JavaScript
/**
* @method remakePlayerElement
* @description YouTube動画を埋め込む要素を再作成
*/
remakePlayerElement() {
const modal = document.querySelector('#modal-video');
modal.removeChild(modal.firstElementChild);
let tag = document.createElement('div');
tag.id = 'player';
modal.appendChild(tag);
}
モーダルウィンドウを閉じるときに埋め込んだYouTube動画を要素ごと削除します。そして再びYouTube動画を埋め込むためのIDを持った要素を作成します。
JavaScript
document.addEventListener('DOMContentLoaded', event => {
document.querySelectorAll('.js-modal-video-open').forEach(element => {
new ToggleModal(element);
});
});
最後に、各動画に対して作成したToggleModal
クラスを作成すれば完成です。
まとめ
JavaScriptの処理は少し長くなってしまいましたが、YouTube動画を埋め込むための便利なAPIが用意されているので、それを使えば簡単にYouTube動画を埋め込むことができます。
本記事を参考にして実装していただければと思います。