★최종 결과물
Modal A
modal a content text
Modal B
modal b content text
1. HTML
Modal 컨테이너와 해당 모달을 작동시킬 button의 DOM에 data-moda-id 속성을 같게 맞춰주어 작동하게 함.
html은 별다를거 없는데,
하단에서 클래스를 불러올때 modal_container 클래스를 가진 모든 DOM을 불러온 뒤,
forEach매서드로 각각 객체를 생성했다.
생성 후, 생성된 개체의 data-modal-id를 얻어온 뒤, [data-modal-id=`${modalId}`] 셀렉터로
modal id가 맞는 모달의 버튼에 open() 이벤트를 달아주었다.
<div class="inner_body">
<button type="button" data-modal-id="modalA">Modal A Open</button>
<button type="button" data-modal-id="modalB">Modal B Open</button>
<div class="modal_container" data-modal-id="modalA">
<div class="modal_wrapper">
<div class="modal_header">
<h3>Modal A</h3>
</div>
<div class="modal_body">
<p>modal a content text</p>
</div>
<div class="modal_button_wrap">
<button type="button">Clode</button>
</div>
</div>
</div>
<div class="modal_container" data-modal-id="modalB">
<div class="modal_wrapper">
<div class="modal_header">
<h3>Modal B</h3>
</div>
<div class="modal_body">
<p>modal b content text</p>
</div>
<div class="modal_button_wrap">
<button type="button">Clode</button>
</div>
</div>
</div>
</div>
<script>
const modalContainers = document.querySelectorAll('.modal_container');
modalContainers.forEach((modalContainer) => {
const modal = new Modal(modalContainer);
const modalId = modalContainer.getAttribute('data-modal-id');
const modalBtn = document.querySelector(`[data-modal-id="${modalId}"]`);
modalBtn.addEventListener('click', () => { modal.open(); });
});
</script>
2. CSS
.inner_body {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
min-height: 400px;
padding: 50px 0;
background: #222;
font-family: 'Poppins', sans-serif;
position: relative;
}
.modal_container {
display: none;
position: absolute;
width: 100%;
height: 100%;
z-index: 9999;
justify-content: center;
align-items: center;
background-color: rgba(0, 0, 0, 0.5);
}
.modal_wrapper {
background-color: #fff;
border-radius: 5px;
padding: 40px;
width: 300px;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
}
.modal_header {
margin-bottom: auto;
}
.modal_header h3 {
margin: 0;
padding: 0;
font-size: 14px;
color: #111;
}
.modal_body p {
font-size: 12px;
color: #555;
}
.modal_button_wrap button {
background: tomato;
color: #fff;
border: none;
border-radius: 100px;
padding: 5px 15px;
cursor: pointer;
}
button[data-modal-id] {
border: 1px solid #ddd;
color: #ddd;
background-color: transparent;
padding: 10px 20px;
cursor: pointer;
margin: 0 10px;;
}
3. JS
class Modal {
constructor(target) {
if(typeof target === 'string'){
this.target = document.querySelector(target);
}else{
this.target = target;
}
this.opend = false;
this.init();
}
init() {
this.target.querySelector('.modal_button_wrap button').addEventListener('click', () => { this.close(); });
}
open() {
if(this.opend){
this.close();
return;
}
this.target.style.display = 'flex';
this.opend = true;
}
close() {
this.target.style.display = 'none';
this.opend = false;
}
}
init()
모달을 open 시키는 버튼은 외부에 있으므로, 모달내에 위치만 close 버튼을 찾아 클릭 시 close 이벤트를 등록해준다.
open(), close()
이전 포스트인 sidebar와 동일하게, open 상태에서 open 매서드가 실행되면 close 되도록 작성.
1. open() 매서드가 실행되면 modal container의 display 속성을 flex로 변경한다.
2. clsoe() 매서드가 실행되면 modal container의 display 속성을 none로 변경한다.