概要
imgタグに属性を添えるだけで、画像をモーダル表示できるコードを作成した。
仕様
イベントが発生して初めてDOM生成する。そのせいでちょっと重い。
#使い方
モーダル化させたいimgタグに
属性 modal-image="hoge.jpeg"
を追加する。
例
<img src="thumbnail.jpeg" modal-image="original.jpeg">
##値
modal-image=" モーダル時に表示させたい画像のパス
"
表示している画像(サムネ画像)とモーダル時の画像が同じであれば値は空でOK。
#コピペコード
あとは下記コードをはりつける。
JavaScript
/**モーダルのDOM生成 */
const img_modal = document.querySelectorAll('[modal-image]');
/*activeクラスを付与*/
img_modal.forEach(function(index) {
index.addEventListener('click', openModal);
});
/**
* DOM生成の後、activeクラスを追加
*/
function openModal() {
this.parentElement.appendChild(makeModal(this));
window.setTimeout(() => {
this.parentElement.getElementsByClassName('gm-modal')[0].classList.add('active');
}, 10);
const el_modal = document.querySelectorAll('.js_close');
el_modal.forEach(function(index) {
index.addEventListener('click', closeModal);
});
}
/**
* activeクラスの削除の後、DOM削除
*/
function closeModal() {
let gmModal = document.getElementsByClassName('gm-modal')[0];
gmModal.classList.remove('active');
window.setTimeout(() => {
gmModal.parentNode.removeChild(gmModal);
}, 500);
}
/**
* モダールのDOMを生成する
* @param el_img modal-image属性をもった要素
*/
function makeModal(el_img) {
let DOM = {
modal : document.createElement('article'),
overlay : document.createElement('div'),
content : document.createElement('div'),
close : document.createElement('button'),
divImg : document.createElement('div'),
img : document.createElement('img'),
}
const cl_name = 'gm-modal';
//.modal
DOM.modal.classList.add(cl_name);
//&__overlay
DOM.overlay.classList.add(cl_name + '__overlay', 'js_close');
//&__content
DOM.content.classList.add(cl_name + '__content');
DOM.divImg .classList.add(cl_name + '__img');
DOM.close.setAttribute('aria-label', 'Close modal');
DOM.close.classList.add(cl_name + '__close', 'js_close');
DOM.close.innerHTML = '×';
//altに値があるなら引き継ぐ
const altValue = el_img.getAttribute('alt');
if (altValue!='') {
DOM.img.alt = altValue;
}
let modalImage = el_img.getAttribute('modal-image');
//属性値が空ならsrcと同じ画像を表示
DOM.img.setAttribute('src', (modalImage=='')? el_img.getAttribute('src') : modalImage);
DOM.divImg.appendChild(DOM.img);
DOM.content.appendChild(DOM.close);
DOM.content.appendChild(DOM.divImg);
DOM.modal.append(DOM.overlay);
DOM.modal.append(DOM.content);
return DOM.modal;
}
CSS
img[modal-image] {
cursor: pointer;
}
.gm-modal {
display: flex;
position: fixed;
justify-content: space-around;
align-items: center;
top: 0;
left: 0;
bottom: 0;
right: 0;
box-sizing: border-box;
padding: 2rem;
background: rgba(0, 0, 0, 0.7);
backdrop-filter: blur(4px);
opacity: 0;
visibility: hidden;
transition: visibility 0.2s, opacity 0.2s;
}
.gm-modal.active {
opacity: 1;
visibility: visible;
}
.gm-modal__overlay {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
cursor: default;
}
.gm-modal__content {
position: relative;
}
.gm-modal__close {
position: absolute;
display: inline-block;
right: 0;
top: -4rem;
border: 0px solid transparent;
outline: 0;
padding: 1rem;
line-height: 1.6rem;
color: #fff;
background-color: transparent;
font-size: 2rem;
cursor: pointer;
}
.gm-modal__img img {
width: auto;
height: auto;
max-width: calc(100vw - 2rem);
max-height: calc(100vh - 8rem);
}
#最後に
cssは細かくプロパティを設定できていないので、タグ名に直接スタイルを当ててると競合してしまうかもしれない。
フィードバックありがとうございます。