เดียววันนี้พาสร้าง Modal Service ด้วย Vanilla JavaScript แบบง่ายๆ แต่ใช้งานได้จริง เอา Modal ไปปรับแต่งได้เลย โดยที่เราไม่พึ่ง Framework ใด ๆ สายเพียวๆ
โครงสร้าง Modal
เริ่มต้นด้วย HTML Template ที่จะใช้เป็น Modal หลักของเรา
ไฟล์ modal.html
<div id="modalTemplate" class="modal">
<div class="modal-content">
<span class="modal-close-btn">✕</span>
<div class="modal-header"></div>
<div class="modal-info"></div>
<div class="modal-actions">
<button class="btn btn-secondary cancel-btn" style="display: none;">ยกเลิก</button>
<button class="btn btn-primary confirm-btn" style="display: none;">ยืนยัน</button>
</div>
</div>
</div>
CSS สำหรับ Modal
ไฟล์ modal.css
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: 1000;
justify-content: center;
align-items: center;
}
.modal-content {
background: white;
border-radius: 8px;
padding: 20px;
max-width: 400px;
width: 90%;
text-align: center;
position: relative;
}
.modal-header {
font-size: 1.2em;
font-weight: bold;
margin-bottom: 10px;
}
.modal-info {
margin-bottom: 20px;
}
.modal-actions {
display: flex;
justify-content: space-around;
}
.modal-close-btn {
position: absolute;
top: 10px;
right: 15px;
cursor: pointer;
font-size: 20px;
}
สร้าง ModalService ด้วย Vanilla JS
มาดู เป็นพระเอกของเรากัน
ไฟล์ modal.service.js
class ModalService {
constructor() {
this.modalElement = document.getElementById('modalTemplate');
this.modalHeader = this.modalElement.querySelector('.modal-header');
this.modalInfo = this.modalElement.querySelector('.modal-info');
this.cancelButton = this.modalElement.querySelector('.cancel-btn');
this.confirmButton = this.modalElement.querySelector('.confirm-btn');
this.onConfirmCallback = null;
this.onCancelCallback = null;
this.cancelButton.addEventListener('click', () => this.close());
this.confirmButton.addEventListener('click', () => this.confirm());
this.modalElement.querySelector('.modal-close-btn').addEventListener('click', () => this.close());
}
open(data, onConfirm, onCancel) {
this.modalHeader.innerHTML = data.title || '';
this.modalInfo.innerHTML = data.content || '...';
this.onConfirmCallback = onConfirm;
this.onCancelCallback = onCancel;
if (data.showConfirmButton) {
this.confirmButton.style.display = 'inline-block';
} else {
this.confirmButton.style.display = 'none';
}
if (data.showCancelButton) {
this.cancelButton.style.display = 'inline-block';
} else {
this.cancelButton.style.display = 'none';
}
this.modalElement.style.display = 'flex';
}
close() {
if (typeof this.onCancelCallback === 'function') {
this.onCancelCallback();
}
this.modalElement.style.display = 'none';
}
confirm() {
if (typeof this.onConfirmCallback === 'function') {
this.onConfirmCallback();
}
this.close();
}
}
การใช้งาน Modal Service
เมื่อทุกอย่างพร้อมแล้ว มาลองใช้งาน ModalService กันครับ
<script>
const modalService = new ModalService();
modalService.open(
{
title: 'แจ้งปิดปรับปรุง',
content: '...',
showConfirmButton: true,
showCancelButton: false,
},
() => {
console.log('ยืนยันการดำเนินการแล้ว');
},
() => {
console.log('การดำเนินการถูกยกเลิก');
}
);
</script>
หรือ อีกตัวอย่างที่ผมแนะนำ คือใช้งานร่วมกับ fetch ช่วยให้ Modal Service ของคุณกลายเป็นเครื่องมือที่ทรงพลัง เพราะเนื้อหาไม่ถูกเขียนแบบ inline แต่ถูกโหลดจากไฟล์แยกต่างหาก และต้องดูที่เคสด้วยว่าเหมาะสมกับงานไหม
<button id="openModal" class="btn btn-primary">เปิด Modal</button>
<script>
document.getElementById('openModal').addEventListener('click', () => {
fetch('./debug.html')
.then(response => response.text())
.then(htmlContent => {
modalService.open(
{
title: 'แจ้งปิดปรับปรุง',
content: htmlContent,
showConfirmButton: true,
showCancelButton: false,
},
() => {
console.log('ยืนยันการดำเนินการแล้ว');
},
() => {
console.log('การดำเนินการถูกยกเลิก');
}
);
})
.catch(error => {
console.error('Error fetching HTML:', error);
});
});
</script>
เพียงแค่นี้เราก็สามารถเปิด Modal สวย ๆ พร้อมปรับแต่งข้อความและปุ่มได้แล้วจ้าา
สรุป
การสร้าง Modal Service ด้วย Vanilla JS ช่วยลดความยุ่งยากและเพิ่มความคล่องตัวในโปรเจ็กต์ คุณสามารถปรับแต่งทุกอย่างได้ง่าย ๆ ทั้งข้อความและปุ่ม แถมยังใช้โค้ดซ้ำได้ในหลายหน้าอีกด้วย