تضيف أدوات مطوّري البرامج في Chrome إمكانية استخدام عناصر الطبقة العليا، ما يسهّل على المطوّرين تصحيح أخطاء الرموز البرمجية التي تستخدِم عناصر الطبقة العليا.
توضّح هذه المقالة عناصر الطبقة العليا، وكيفية مساعدة "أدوات المطوّر" في عرض محتوى الطبقة العليا لفهم بنية DOM التي تحتوي على عناصر الطبقة العليا وتصحيح أخطاءها، وكيفية تنفيذ ميزات الطبقة العليا في "أدوات المطوّر".
ما هي الطبقة العليا وعناصر الطبقة العليا؟
ماذا يحدث تحديدًا داخليًا عند فتح <dialog>
كإطار مشروط؟ 🤔
ويتم وضعه في طبقة علوية. يتم عرض محتوى الطبقة العليا فوق كل المحتوى الآخر. على سبيل المثال، يجب أن يظهر مربّع حوار مشروط فوق كل محتوى DOM آخر، لذا يعرض المتصفّح هذا العنصر تلقائيًا في "الطبقة العليا" بدلاً من إجبار المؤلّفين على التعامل يدويًا مع z-index. يظهر عنصر الطبقة العلوية فوق عنصر آخر حتى مع أعلى قيمة لسمة z-index.
يمكن وصف الطبقة العلوية بأنّها "أعلى طبقة يتمّ تجميعها". يحتوي كل مستند على إطار عرض واحد مرتبط به، وبالتالي طبقة علوية واحدة أيضًا. يمكن أن تكون هناك عناصر متعدّدة داخل الطبقة العليا في الوقت نفسه. وعند حدوث ذلك، يتم تجميعها فوق بعضها، ويكون آخر نموذج في الأعلى. بعبارة أخرى، يتم وضع جميع عناصر الطبقة العليا في حزمة الأخير يخرج أولاً (LIFO) في الطبقة العليا.
عنصر <dialog>
ليس العنصر الوحيد الذي يعرضه المتصفّح في طبقة علوية. في الوقت الحالي، تتضمّن الطبقة العليا العناصر التالية:
المربّعات المنبثقة والمربّعات الحوارية النمطية والعناصر في وضع ملء الشاشة.
راجِع عملية تنفيذ مربّع الحوار التالية:
<main>
<button onclick="window.dialog.showModal();">Open Dialog</button>
</main>
<dialog id="dialog"></dialog>
في ما يلي عرض توضيحي يتضمن مربّعَي حوار تم تطبيق أنماط على الخلفيات الخاصة بهما (الخلفيات الموضّحة أدناه):
ما هو المقصود بالخلفية؟
لحسن الحظ، تتوفّر طريقة لتخصيص المحتوى أسفل عنصر الطبقة العليا.
يحتوي كل عنصر في الطبقة العليا على عنصر زائف في CSS يُسمى خلفية.
الخلفية هي مربّع بحجم إطار العرض يتم عرضه مباشرةً أسفل أي عنصر من الطبقة العليا. يتيح العنصر النائب ::backdrop
إخفاء كل العناصر التي تقع أسفل العنصر أو إخفاءها تمامًا أو تطبيق أسلوب عليها عندما يكون العنصر هو الأعلى في الطبقة العليا.
عند جعل عناصر متعددة مشروطة، يرسم المتصفّح الخلفية مباشرةً أسفل العنصر الأقرب إلى المقدّمة وفوق العناصر الأخرى التي تظهر على الشاشة الكاملة.
في ما يلي كيفية تصميم خلفية:
/* The browser displays the backdrop only when the dialog.showModal() function opens the dialog.*/
dialog::backdrop {
background: rgba(255,0,0,.25);
}
كيف يمكن عرض الخلفية الأولى فقط؟
يحتوي كل عنصر من عناصر الطبقة العليا على خلفية تنتمي إلى حزمة طبقة عليا. تم تصميم الخلفيات هذه لتتداخل مع بعضها، لذا إذا لم تكن شفافية الخلفية 100%، ستظهر الخلفيات تحتها.
إذا كنت تريد إظهار الخلفية الأولى فقط في حزمة الطبقة العليا، يمكنك تحقيق ذلك من خلال تتبُّع معرّفات العناصر في حزمة الطبقة العليا.
إذا لم يكن العنصر المُضاف هو العنصر الأول في الطبقة العليا، تطبّق الدالة التي يتمّ استدعاؤها عند وضع العنصر في الطبقة العليا فئة hiddenBackdrop
على ::backdrop
. تتم إزالة هذه الفئة عند إزالة العنصر من الطبقة العليا.
اطّلِع على الرمز في هذا المثال التجريبي:
تصميم دعم الطبقة العليا في أدوات مطوّري البرامج
يساعد توافق "أدوات المطوّرين" مع الطبقة العليا المطوّرين في فهم مفهوم الطبقة العليا وعرض كيفية تغيُّر محتوى الطبقة العليا. تساعد هذه الميزات المطوّرين في تحديد ما يلي:
- العناصر في الطبقة العليا في أي وقت وترتيبها
- العنصر في أعلى الحزمة في أي وقت
بالإضافة إلى ذلك، تساعد أدوات المطوّرين في عرض موضع العنصر النائب للخلفية في حزمة الطبقة العليا. على الرغم من أنّه ليس عنصرًا في الشجرة، إلا أنّه يلعب دورًا مهمًا في آلية عمل الطبقة العليا ويمكن أن يكون مفيدًا للمطوّرين.
باستخدام ميزات الدعم من المستوى الأعلى، يمكنك إجراء ما يلي:
- راقِب العناصر التي تكون في حزمة الطبقة العليا في أي وقت. تتغيّر حزمة تمثيل الطبقة العليا ديناميكيًا عند إضافة عناصر أو إزالتها من الطبقة العليا.
- الاطّلاع على موضع العنصر في حزمة الطبقة العليا
- الانتقال من عنصر الطبقة العليا أو العنصر النائب للخلفية في العناصر في الشجرة إلى العنصر أو العنصر النائب للخلفية في حاوية تمثيل الطبقة العليا والعكس
لنطّلِع على كيفية استخدام هذه الميزات.
حاوية الطبقة العليا
للمساعدة في عرض عناصر الطبقة العليا بشكل مرئي، تضيف أدوات المطوّرين حاوية الطبقة العليا إلى شجرة العناصر. وتظهر بعد علامة الإغلاق </html>
.
تتيح لك هذه الحاوية مراقبة العناصر في حزمة الطبقة العليا في أي وقت. حاوية الطبقة العليا هي قائمة بروابط تؤدي إلى عناصر الطبقة العليا وخلفياتها. تتغيّر حزمة تمثيل الطبقة العليا ديناميكيًا عند إضافة عناصر أو إزالتها من الطبقة العليا.
للعثور على عناصر الطبقة العليا ضمن شجرة العناصر أو حاوية الطبقة العليا، انقر على الروابط من تمثيل عنصر الطبقة العليا في حاوية الطبقة العليا إلى العنصر نفسه في شجرة العناصر والعكس.
للانتقال من عنصر حاوية الطبقة العليا إلى عنصر الشجرة في الطبقة العليا، انقر على الزر إظهار بجانب العنصر في حاوية الطبقة العليا.
للانتقال من عنصر الشجرة في الطبقة العليا إلى الرابط في حاوية الطبقة العليا، انقر على شارة الطبقة العليا بجانب العنصر.
يمكنك إيقاف أي شارة، بما في ذلك شارة الطبقة العليا. لإيقاف الشارات، انقر بزر الماوس الأيمن على أي شارة، واختَر إعدادات الشارة وأزِل العلامات بجانب الشارات التي تريد إخفاءها.
ترتيب العناصر في حزمة الطبقة العلوية
تعرِض حاوية الطبقة العلوية العناصر كما تظهر في الحزمة ولكن بترتيب عكسي. أعلى عنصر الحزمة هو العنصر الأخير في قائمة العناصر لحاوية الطبقة العليا. وهذا يعني أنّ العنصر الأخير في قائمة حاويات الطبقة العليا هو العنصر الذي يمكنك التفاعل معه حاليًا في المستند.
تشير الشارات بجانب عناصر الشجرة إلى ما إذا كانت العناصر تنتمي إلى الطبقة العليا وتحتوي على رقم موضع عنصر في الحزمة.
في لقطة الشاشة هذه، تتألف حزمة الطبقة العليا من عنصرَين، مع وضع العنصر الثاني في أعلى الحزمة. إذا أزلت العنصر الثاني، سيتم نقل العنصر الأول إلى الأعلى.
الخلفيات في حاوية الطبقة العليا
كما ذكرنا أعلاه، يحتوي كل عنصر من الطبقة العليا على عنصر زائف في CSS يُسمى backdrop. يمكنك تصميم هذا العنصر، لذا من المفيد أيضًا فحصه والاطّلاع على تمثيله.
في شجرة العناصر، يظهر عنصر الخلفية قبل العلامة الإغلاق للعنصر الذي ينتمي إليه. ومع ذلك، في حاوية الطبقة العليا، يتم إدراج رابط الخلفية مباشرةً فوق عنصر الطبقة العليا الذي ينتمي إليه.
التغييرات في شجرة نموذج العناصر في المستند
ElementsTreeElement
، الفئة المسؤولة عن إنشاء عناصر شجرة نموذج عناصر المستند الفردية وإدارتها في DevTools، لم تكن كافية لتنفيذ حاوية الطبقة العليا.
لعرض حاوية الطبقة العليا كنقطت في الشجرة، أضفنا فئة جديدة تنشئ عناصر شجرة DevTools. في السابق، كانت الفئة المسؤولة عن إنشاء شجرة عناصر DevTools تبدأ كل TreeElement
باستخدام DOMNode
، وهي فئة تحتوي على backendNodeId
وخصائص أخرى ذات صلة بالخلفية. يتمّ تعيين backendNodeId
بدوره في الخلفية.
يجب أن تعمل عقدة حاوية الطبقة العليا، التي تحتوي على قائمة بالروابط المؤدية إلى عناصر الطبقة العليا، كعقدة عنصر شجرة عادية. ومع ذلك، هذه العقدة ليست عقدة DOM "حقيقية" ولا تحتاج الخلفية إلى إنشاء عقدة حاوية الطبقة العليا.
لإنشاء عقدة واجهة تمثل الطبقة العليا، أضفنا نوعًا جديدًا من عقدة واجهة يتم إنشاؤها بدون DOMNode
. عنصر الحاوية في الطبقة العليا هو أول عقدة في الواجهة الأمامية لا تحتوي على DOMNode
، ما يعني أنّه لا يظهر إلا في الواجهة الأمامية ولا "تعرف" عليه الواجهة الخلفية. للحصول على السلوك نفسه مثل العقد الأخرى، أنشأنا فئة TopLayerContainer
جديدة تُوسّع فئة UI.TreeOutline.TreeElement
المسؤولة عن سلوك العقد في الواجهة الأمامية.
لتحقيق الموضع المطلوب، تُرفِق الفئة التي تعرِض عنصرًا TopLayerContainer
كعنصر شقيق تالي لعلامة <html>
.
تشير شارة الطبقة العليا الجديدة إلى أنّ العنصر في الطبقة العليا، وتعمل كرابط يؤدي إلى اختصار هذا العنصر في عنصر TopLayerContainer
.
التصميم الأوّلي
في البداية، كانت الخطة هي تكرار عناصر الطبقة العليا في حاوية الطبقة العليا بدلاً من إنشاء قائمة بروابط تؤدي إلى العناصر. لم نفّذ هذا الحلّ بسبب طريقة جلب العناصر الفرعية للعنصر في "أدوات مطوّري البرامج". يحتوي كل عنصر على مؤشر رئيسي يُستخدَم في جلب العناصر الفرعية، ومن المستحيل أن يكون هناك مؤشرات متعددة. لذلك، لا يمكننا الحصول على عقدة يتم توسيعها بشكل صحيح وتتضمّن جميع العناصر الفرعية في مواضع متعدّدة في الشجرة. بوجهٍ عام، لم يتم إنشاء النظام مع مراعاة الأشجار الفرعية المكرّرة.
ووصلنا إلى حلّ وسط يتمثل في إنشاء روابط إلى عقد DOM في الواجهة الأمامية بدلاً من تكرار هذه العقد. الفئة المسؤولة عن إنشاء روابط إلى العناصر في "أدوات مطوّري البرامج" هي ShortcutTreeElement
، التي تُوسّع UI.TreeOutline.TreeElement
. يعرض ShortcutTreeElement
السلوك نفسه الذي يعرضه عناصر شجرة DOM الأخرى في DevTools، ولكنّه لا يحتوي على عقدة مقابلة في الخلفية ويحتوي على زر يرتبط بعنصر ElementsTreeElement
.
تحتوي كل عقدة ShortcutTreeElement
من العقدة في الطبقة العليا على عنصر ShortcutTreeElement
فرعي يرتبط بتمثيل عنصر زائف ::backdrop
في شجرة DOM في DevTools.
التصميم الأولي:
تغييرات بروتوكول "أدوات مطوّري البرامج في Chrome" (CDP)
لتنفيذ ميزة الدعم في الطبقة العليا، يجب إجراء تغييرات على بروتوكول أدوات مطوّري البرامج في Chrome (CDP). يعمل بروتوكول CDP كبروتوكول اتصال بين أدوات مطوري البرامج في Chrome وChromium.
يجب إضافة ما يلي:
- أمر للاتصال من الواجهة الأمامية في أي وقت
- حدث يتم تشغيله في الواجهة الأمامية من جهة الخلف
CDP: الأمر DOM.getTopLayerElements
لعرض عناصر الطبقة العليا الحالية، نحتاج إلى أمر تجريبي جديد في CDP يعرض قائمة بأرقام تعريف العقد للعناصر التي تقع في الطبقة العليا. تستدعي "أدوات مطوّري البرامج" هذا الأمر عند فتحها أو عند تغيير عناصر الطبقة العليا. يظهر الأمر على النحو التالي:
# Returns NodeIds of the current top layer elements.
# Top layer renders closest to the user within a viewport, therefore, its elements always
# appear on top of all other content.
experimental command getTopLayerElements
returns
# NodeIds of the top layer elements.
array of NodeId nodeIds
CDP: حدث DOM.topLayerElementsUpdated
للحصول على القائمة المحدّثة لعناصر الطبقة العليا، نحتاج إلى كل تغيير في عناصر الطبقة العليا لبدء حدث تجريبي في "إدارة الموافقة". يُعلم هذا الحدث الواجهة الأمامية بالتغيير الذي يستدعي بعد ذلك الأمر DOM.getTopLayerElements
ويتلقّى قائمة العناصر الجديدة.
يظهر الحدث على النحو التالي:
# Called by the change of the top layer elements.
experimental event topLayerElementsUpdated
اعتبارات متعلقة ببرنامج CDP
كانت هناك خيارات متعدّدة حول كيفية تنفيذ دعم CDP للطبقة العليا. كان الخيار الآخر الذي فكّرنا فيه هو إنشاء حدث يعرض قائمة بعناصر الطبقة العليا بدلاً من إبلاغ الواجهة الأمامية فقط بإضافة عنصر من الطبقة العليا أو إزالته.
بدلاً من ذلك، يمكننا إنشاء حدثَين بدلاً من الأمر: topLayerElementAdded
وtopLayerElementRemoved
. في هذه الحالة، سنتلقّى عنصرًا وسنحتاج إلى إدارة صفيف عناصر الطبقة العليا في الواجهة الأمامية.
في الوقت الحالي، يستدعي حدث الواجهة الأمامية الأمر getTopLayerElements
للحصول على قائمة بالعناصر المعدَّلة. إذا أردنا إرسال قائمة بالعناصر أو عنصر معيّن أدّى إلى التغيير في كل مرة يتم فيها تشغيل حدث، يمكننا تجنُّب خطوة واحدة من طلب الأمر.
وفي هذه الحالة، لن تتمكّن الواجهة الأمامية من التحكّم في العناصر التي يتمّ دفعها.
لقد نفّذنا ذلك بهذه الطريقة لأنّنا نرى أنّه من الأفضل أن تحدّد الواجهة الأمامية وقت طلب العقد في الطبقة العليا. على سبيل المثال، إذا كانت الطبقة العليا مصغّرة في واجهة المستخدم أو كان المستخدم يستخدم لوحة DevTools لا تحتوي على شجرة العناصر، لن يكون هناك حاجة إلى الحصول على العقد الإضافية التي يمكن أن تكون في مستويات أعمق من الشجرة.