تريد إبقاء نافذة حوار ظاهرة عند محاولة إغلاقها، لكن وضع المنع داخل close يأتي متأخرًا: هذا الحدث يبلغك بأن الإغلاق وقع. [2]
اعترض طلب الإغلاق في cancel، واستخدم close لمتابعة الإغلاق بعد حدوثه. [1][2]
الخلاصة السريعة
- افتح المثال باستخدام showModal() لتجرب نافذة مشروطة تمنع التفاعل مع بقية المستند. [4]
- يمكن منع الإغلاق داخل cancel باستدعاء preventDefault() عندما يكون الحدث قابلًا للإلغاء. [1][6]
- حدث close إشعار بإغلاق النافذة، وهو غير قابل للإلغاء ولا يصعد إلى الأب. [2]
- الاستدعاء المباشر لـ close() يغلق النافذة دون المرور بحدث cancel. [3][6]
- احتفظ بزر إغلاق صريح يعمل، ولا تجعل منع Escape سببًا لاحتجاز المستخدم. [5]
جهّز نافذة الاختبار
افتح المثال باستخدام showModal() لتجرب نافذة مشروطة تمنع التفاعل مع بقية المستند. [4]
ضع HTML في body، ثم اجمع مقاطع JavaScript الأربعة في script بعده. زر الفتح يمسح السجل السابق ويفتح النافذة. اترك مربع الاختيار محددًا للمحاولة الأولى. لا تستبدل showModal() بإضافة open يدويًا؛ نختبر هنا نافذة مشروطة، لا مجرد عنصر ظاهر. [4][5]
مرّر الشيفرة أفقيًا عند الحاجة.
<button id="launch" type="button">افتح التجربة</button>
<dialog id="panel" aria-labelledby="heading">
<h2 id="heading">تجربة الإغلاق</h2>
<label><input id="block" type="checkbox" checked>
امنع طلب الإغلاق</label>
<button id="finish" type="button">إغلاق الآن</button>
</dialog>
<pre id="log" dir="ltr"></pre>مرّر الشيفرة أفقيًا عند الحاجة.
const panel = document.querySelector("#panel");
const block = document.querySelector("#block");
const log = document.querySelector("#log");
document.querySelector("#launch").onclick = () => {
log.textContent = "";
panel.showModal();
};اعترض الطلب قبل الإغلاق
يمكن منع الإغلاق داخل cancel باستدعاء preventDefault() عندما يكون الحدث قابلًا للإلغاء. [1][6]
اضغط Escape بعد الفتح. عند نجاح المنع يبقى الحوار، ويسجل المثال cancel مع قيمة prevented تساوي true. أزل علامة الاختيار واضغط المفتاح؛ يصبح المنع false ويتبعه close. تحقق من السجل والحالة معًا، ولا تستنتج أن النافذة أغلقت من وصول cancel وحده. [1]
نفحص cancelable صراحة لأن آلية طلب الإغلاق في المواصفة تمرر إمكانية المنع إلى الحدث؛ ليست هذه الشيفرة ضمانًا لتعطيل كل وسيلة خروج في كل بيئة. في Edge الذي اختبرناه، أغلق ضغط Escape مرة ثانية الحوار مع حدث غير قابل للإلغاء، رغم بقاء المربع محددًا. [6]
مرّر الشيفرة أفقيًا عند الحاجة.
panel.addEventListener("cancel", event => {
if (block.checked && event.cancelable) event.preventDefault();
log.textContent += `cancel: prevented=${event.defaultPrevented}\n`;
});راقب الإغلاق بعد اكتماله
حدث close إشعار بإغلاق النافذة، وهو غير قابل للإلغاء ولا يصعد إلى الأب. [2]
أضف المستمع إلى panel نفسه. يعرض السجل قيمة cancelable مساوية لـ false عند الإغلاق، فلا تنقل preventDefault() إلى هذا المعالج وتتوقع إبقاء الحوار. يمكن أن تستخدمه لتحديث واجهة الصفحة بعد انتهاء النافذة. انتبه أيضًا إلى الفرق بين close اسم الحدث، وclose() استدعاء الدالة الذي يبدأ الإغلاق. [2]
مرّر الشيفرة أفقيًا عند الحاجة.
panel.addEventListener("close", event => {
log.textContent += `close: cancelable=${event.cancelable}\n`;
});قارن الزر بمفتاح Escape
الاستدعاء المباشر لـ close() يغلق النافذة دون المرور بحدث cancel. [3][6]
أعد الفتح مع تفعيل المنع، ثم اضغط «إغلاق الآن». يغلق الزر النافذة ويظهر close وحده في السجل الجديد. هذه نتيجة مقصودة: الزر ينفذ الإغلاق مباشرة؛ لا يطلب موافقة معالج cancel. لذلك لا تضع قاعدة يجب أن تفحص كل زر داخل cancel وحده. [3][6]
مرّر الشيفرة أفقيًا عند الحاجة.
document.querySelector("#finish").onclick = () => panel.close();اترك مخرجًا واضحًا
احتفظ بزر إغلاق صريح يعمل، ولا تجعل منع Escape سببًا لاحتجاز المستخدم. [5]
منع المفتاح هنا أداة لتوضيح دورة الحدث، وليس إعدادًا مقترحًا لكل نافذة. يتوقع مستخدم لوحة المفاتيح أن يغلق Escape الحوار؛ اجعل السلوك المعتاد متاحًا في تصميمك. جرّب الوصول إلى زر الإغلاق وتشغيله بالمفاتيح أيضًا، وتحقق من عمله على جهاز لا يملك لوحة مفاتيح. وجود الزر الواضح مهم حتى عندما تكون لديك طريقة أخرى للإغلاق. [5]
المصادر ومتابعة القراءة
- MDN: حدث طلب الإغلاق cancel (يفتح في نافذة جديدة)developer.mozilla.org
- MDN: إشعار الإغلاق close (يفتح في نافذة جديدة)developer.mozilla.org
- MDN: الإغلاق المباشر بالدالة close (يفتح في نافذة جديدة)developer.mozilla.org
- MDN: فتح نافذة مشروطة (يفتح في نافذة جديدة)developer.mozilla.org
- MDN: إتاحة استخدام dialog (يفتح في نافذة جديدة)developer.mozilla.org
- WHATWG: خطوات الطلب والإغلاق (يفتح في نافذة جديدة)html.spec.whatwg.org
أُعدّ هذا المقال بصياغة عربية أصلية بالاستناد إلى المصادر أعلاه، وهو مدخل تمهيدي إلى الموضوع. اقرأ منهجية المحتوى وحدوده.