レシピサイトをつくる(モーダルウィンドウでリンク先を表示する-JavaScript)
完成イメージ
記事一覧のどれかをクリックすると、モーダルで投稿詳細ページが表示されます。
HTML
<ul class="modal-recipe">
<li>
<a class="js-modal-recipe" href="https://~~"></a>
</li>
</ul>
ulのmodal-recipeはcssスタイルをあてます。
aのjs-modal-recipeとhrefのリンクはJavaScriptで使います。
JavaScript
JavaScript全コード
// タグを出力してオブジェクトを作る
const printRecipeModal = recipeUrl => {
let modal = document.createElement('div');
modal.id = "modalRecipe";
modal.classList.add('ed-modal');
modal.innerHTML = `
<div id="modalOverlay">
<div class="modalContent">
<div id="closeModal" class="ed-closeModal"></div>
<div class="recipe">
<iframe src="${recipeUrl}" frameborder="0" allowfullscreen> </iframe>
<div>
</div>
</div>`;
document.body.appendChild(modal);
closeModal(modal);
};
// モーダルを閉じる
const closeModal = modal => {
document.getElementById('closeModal').addEventListener('click', () => {
document.body.removeChild(modal);
});
document.getElementById('modalOverlay').addEventListener('click', () => {
document.body.removeChild(modal);
});
window.addEventListener('keyup', e => {
if (e.key === 'Escape') {
document.body.removeChild(modal);
}
});
};
// モーダルを開く
const openRecipeModal = selector => {
let linksElements = [...document.querySelectorAll(selector)];
linksElements.forEach((el) => {
el.addEventListener('click', e => {
e.preventDefault();
printRecipeModal(el.href);
});
});
};
openRecipeModal('.js-modal-recipe');
モーダルを開く関数では、①<a>タグの配列を取得して、②タグを生成する関数に、クリックした<a>タグのhrefリンクを渡しています。
タグを生成する関数では、受け取ったhrefリンクを<iframe>タグのsrc部分に埋め込み、document.body.appendChild(modal);でHTMLにモーダル部分を追加しています。
モーダルを閉じる関数では、バツボタンをクリック or モーダルの外側をクリック or Escapeキーをクリックして離した(keyup)時に、document.body.removeChild(modal);でHTMLからモーダル部分を削除しています。
CSS
CSS全コード
/* カード */
ul.modal-recipe {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
gap: 10px;
}
ul.modal-recipe li a {
display: block;
text-align: center;
}
ul.modal-recipe li a:hover {
box-shadow: 0 15px 30px -5px rgb(0 0 0 / 15%), 0 0 5px rgb(0 0 0 / 10%);
transform: translateY(-4px);
text-decoration: none;
}
ul.modal-recipe li a img {
border-radius: 50%;
}
ul.modal-recipe li a p {
color: #313131;
padding: 5px 0;
font-size: .8rem;
}
/* modal */
.ed-modal {
position: fixed;
width: 100%;
height: 100%;
left: 0;
top: 0;
background: rgba(0, 0, 0, 0.9);
display: flex;
z-index: 9999;
}
div#modalOverlay {
width: 100%;
height: 100%;
display: flex;
cursor: pointer;
}
.ed-closeModal {
position: absolute;
top: -35px;
right: 5px;
cursor: pointer;
width: 1.5rem;
height: 1.5rem;
opacity: 0.5;
}
.ed-closeModal::before, .ed-closeModal::after {
content: "";
width: 35px;
height: 2px;
background: #fff;
position: absolute;
top: 0;
transform: rotate(45deg);
transform-origin: top left;
}
.ed-closeModal::before {
left: 0;
}
.ed-closeModal::after {
right: 0;
transform: rotate(-45deg);
transform-origin: top right;
}
.modalContent {
width: 100%;
max-width: 800px;
margin: auto;
position: relative;
}
.recipe {
width: 100%;
position: relative;
/* height: 0; */
height: 90vh;
padding-bottom: 56.25%;
overflow: hidden;
filter: drop-shadow(0px 2px 5px #313131);
animation: fadeIn 1.2s ease 0s 1 normal;
}
.recipe iframe {
width: 100%;
position: absolute;
top: 0;
left: 0;
height: 100%;
}
@keyframes fadeIn {
0% {
opacity: 0;
transform: translateY(30px);
}
100% {
opacity: 1;
}
}
@media screen and (max-width: 767px) {
/* (ここにモバイル用スタイルを記述) */
ul.modal-recipe li {
width: 100%;
}
}
ul.modal-recipeでは記事一覧の見た目を調整します。