Kodokon kodokon.com

HTML التفاعلي الحديث: dialog وdetails وpopover وcontenteditable

استبدل مكتبات واجهتك بالبدائيات الأصلية في HTML الحديث: النوافذ الحوارية النمطية، والأكورديونات الحصرية، والنوافذ المنبثقة، والمناطق القابلة للتحرير.

10 دقيقة · 3 أسئلة

افتح هذا الدرس في Kodokon

يحلّ <dialog> أصليًا ما جمّعته سنوات من مكتبات النوافذ النمطية بحلول ملتوية. يُسقِط showModal() العنصر في الطبقة العليا (top layer) - فوق أي z-index -، ويجعل بقية المستند خاملة (inert) (لا تركيز، لا نقرات) ويكشف العنصر الزائف ::backdrop. أما show() فيعرض نافذة حوارية غير نمطية، بلا خمول وبلا خلفية. وتضيف السمة الحديثة closedby=any الإغلاق بالنقر خارجها.

HTML
<dialog id="confirm-dlg">
  <form method="dialog">
    <p>Delete this item?</p>
    <button value="cancel">Cancel</button>
    <button value="ok">Confirm</button>
  </form>
</dialog>
نموذج method=dialog يُغلق النافذة الحوارية دون طلب شبكي.

نموذج <form method=dialog> يُغلق النافذة الحوارية دون إرسال شبكي: تصبح value الخاصة بالزر المُشغِّل هي dialog.returnValue، التي يتيح لك حدث close قراءتها. يُغلق مفتاح Escape نافذة حوارية نمطية بإطلاق cancel أولًا، ويمكنك إلغاؤه بـ preventDefault() إذا كان الإدخال جاريًا.

JAVASCRIPT
const dlg = document.getElementById("confirm-dlg");
dlg.showModal();
dlg.addEventListener("close", () => {
  console.log(dlg.returnValue); // "ok" or "cancel"
});
استرجاع اختيار المستخدم عند الإغلاق.

تغطّي واجهة Popover القوائم والتلميحات الغنية والإشعارات (toasts) دون JavaScript: ضع popover على العنصر وpopovertarget على زر، ويتولّى المتصفح الطبقة العليا والصرف الخفيف (light dismiss) (النقر خارجها، Escape) والإغلاق المتبادل للنوافذ المنبثقة من نوع auto. وعلى عكس showModal()، لا تجعل النافذة المنبثقة الصفحة خاملة. ويتيح لك الحدثان beforetoggle وtoggle إلغاء أو مراقبة كل انتقال.

HTML
<button popovertarget="user-menu">Menu</button>
<div id="user-menu" popover>
  <button>Profile</button>
  <button>Log out</button>
</div>
قائمة كاملة، دون سطر واحد من JavaScript.

يوفّر <details> محتوى قابلًا للطي وميسّرًا (accessible) دون نص برمجي، وتُنشئ سمة name مشتركة مجموعة حصرية: فتح واحد يُغلق الآخرين. ويُطلَق الحدث toggle هناك عند كل تغيير في الحالة. أما على جانب التحرير، فـ contenteditable يحوّل أي عنصر إلى منطقة إدخال غنية؛ ويمنع متغيّره plaintext-only أي ترميز، ويحلّ الحدث beforeinput بشكل مفيد محلّ واجهة document.execCommand المهجورة.

HTML
<details name="faq" open>
  <summary>Delivery time?</summary>
  <p>Within 48 hours.</p>
</details>
<details name="faq">
  <summary>Return policy?</summary>
  <p>Within 30 days.</p>
</details>
الاسم المشترك يُنتج أكورديونًا حصريًا أصليًا.

اختبار المعرفة

تأكّد من أنك تذكّرت النقاط الأساسية في هذا الدرس.

  1. ماذا يجلب showModal() مقارنةً بـ show()؟
    • يوقف تنفيذ JavaScript حتى إغلاق النافذة الحوارية
    • يضع النافذة الحوارية في الطبقة العليا، ويجعل بقية المستند خاملة، ويُفعّل ::backdrop
    • يمنع فقط الصفحة من التمرير
  2. ماذا تُنتج سمة name متطابقة على عدة عناصر <details>؟
    • تُرسَل معًا في النموذج الأب
    • لا شيء: name ليست سمة صالحة على details
    • أكورديون حصري: فتح واحد يُغلق الآخرين تلقائيًا
  3. ما الفرق السلوكي بين نافذة منبثقة من نوع auto وأخرى من نوع manual؟
    • auto تحصل على الصرف الخفيف (النقر خارجها، Escape) وتُغلق النوافذ المنبثقة الأخرى من نوع auto؛ أما manual فتبقى مفتوحة حتى تُغلق صراحة
    • manual لا يمكن وضعها في الطبقة العليا
    • auto تفتح من تلقاء نفسها عند تحميل الصفحة