Hộp thoại phụ trợ hiện đại thường hỗ trợ tính năng "đóng nhanh", cho phép người dùng đóng hộp thoại bằng cách nhấp hoặc nhấn vào phông nền (khu vực bên ngoài hộp thoại). Thuộc tính closedby cung cấp một cách khai báo để bật hành vi này mà không cần JavaScript tuỳ chỉnh.
Triển khai
Cách bật tính năng đóng nhanh:
- Thêm
closedby="any"vào phần tử<dialog>. - Mở hộp thoại bằng
dialog.showModal().
Giá trị thuộc tính
any: Cho phép đóng nhanh (nhấp vào phông nền), "yêu cầu đóng" (phímEsc) và cơ chế của nhà phát triển (ví dụ:dialog.close()).closerequest: Chỉ bật "yêu cầu đóng" và cơ chế dành cho nhà phát triển. Đây là chế độ mặc định cho hộp thoại phương thức.none: Chỉ cơ chế của nhà phát triển mới có thể đóng hộp thoại.
Tạo kiểu cho phông nền
Khi một hộp thoại được mở dưới dạng phương thức bằng showModal(), trình duyệt sẽ tạo một phần tử giả ::backdrop. Phông nền này bao phủ toàn bộ khung nhìn và nằm ngay phía sau hộp thoại.
/* Style the backdrop to indicate the dialog is modal */
dialog::backdrop {
background-color: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(2px); /* Optional: add blur for modern browsers */
}
Ví dụ
<!-- MANDATORY: Use closedby="any" to enable light-dismiss behavior -->
<dialog id="myDialog" closedby="any" aria-labelledby="dialogTitle">
<form method="dialog">
<h2 id="dialogTitle">Feedback</h2>
<p>Click outside this box or press Esc to dismiss.</p>
<button type="submit">Close</button>
</form>
</dialog>
<button onclick="document.getElementById('myDialog').showModal()">Open Dialog</button>
Các quy tắc ràng buộc và hỗ trợ tiếp cận
- BẮT BUỘC: Sử dụng
closedby="any"để bật tính năng đóng khi nhấp ra ngoài một cách rõ ràng. - BẮT BUỘC: Luôn mở hộp thoại phương thức bằng
showModal(). Điều này đảm bảo hộp thoại nằm ở lớp trên cùng, tiêu điểm được giữ lại và phímEscđược xử lý. - NÊN: Sử dụng
aria-labelledbyhoặcaria-labelđể cung cấp tên thành phần hỗ trợ tiếp cận cho hộp thoại. - KHÔNG: Sử dụng
closedbycho hộp thoại không phụ thuộc (mở bằngshow()), vì các hộp thoại này không có phông nền và sẽ không kích hoạt tính năng đóng nhanh. - KHÔNG: Sử dụng sự kiện
clickcho logic quan trọng cần xảy ra trước khi đóng; thay vào đó, hãy theo dõi các sự kiệnclosehoặccancel.
Chiến lược dự phòng
BẮT BUỘC: Đối với những trình duyệt chưa hỗ trợ closedby, bạn phải triển khai một phương án dự phòng cho tính năng đóng nhanh bằng cách kiểm tra xem có lượt nhấp nào xảy ra bên ngoài ranh giới nội dung của hộp thoại hay không bằng cách sử dụng tập lệnh sau:
const dialog = document.querySelector('dialog');
// Fallback for browsers without closedby support
if (!('closedBy' in HTMLDialogElement.prototype)) {
dialog.addEventListener('click', (event) => {
// 1. When clicking the backdrop, the event target is the dialog element itself.
// Ignore clicks where the target is a child element inside the dialog.
if (event.target !== dialog) return;
// 2. Check if the click coordinates fall within the dialog's content box.
// This distinguishes between a click on the backdrop vs a click on the dialog's background/padding.
const rect = dialog.getBoundingClientRect();
const isDialogContent = (
rect.top <= event.clientY &&
event.clientY <= rect.top + rect.height &&
rect.left <= event.clientX &&
event.clientX <= rect.left + rect.width
);
if (isDialogContent) return;
// 3. Since the click was outside the content area (on the backdrop), manually close the dialog.
dialog.close();
});
}