Skip to content

Instantly share code, notes, and snippets.

@whitia
Last active April 8, 2022 05:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save whitia/700a47866706bb0fd5ff76bae34511fd to your computer and use it in GitHub Desktop.
Save whitia/700a47866706bb0fd5ff76bae34511fd to your computer and use it in GitHub Desktop.
【CSS+JS】モーダルウィンドウを表示しその中にYouTube動画を動的に埋め込む
<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>
.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
/**
* @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);
});
});
.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;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment