Modal Widget
Build a reusable modal dialog with jQuery that traps focus, handles Escape, and is accessible.
Build a reusable modal dialog with jQuery that traps focus, handles Escape, and is accessible.
function openModal($modal) {
const $lastFocus = $(document.activeElement);
$modal.removeAttr("hidden").attr("aria-modal","true");
$modal.find("[autofocus], button").first().focus();
// Focus trap
$modal.on("keydown.modal", function(e) {
if (e.key !== "Tab") return;
const $focusable = $modal.find("a,button,input,textarea,[tabindex]:not([tabindex=-1])").filter(":visible");
const first = $focusable[0], last = $focusable[$focusable.length-1];
if (e.shiftKey && document.activeElement === first) { last.focus(); e.preventDefault(); }
else if (!e.shiftKey && document.activeElement === last) { first.focus(); e.preventDefault(); }
});
$(document).on("keydown.modal", e => { if (e.key === "Escape") closeModal($modal, $lastFocus); });
}
function closeModal($modal, $return) { $modal.attr("hidden","").off("keydown.modal"); $(document).off("keydown.modal"); $return.focus(); }
Focus trapping inside modals is an accessibility requirement — users should not be able to tab outside the open dialog.