Chrome DevTools เพิ่มการรองรับองค์ประกอบเลเยอร์บนสุด ซึ่งช่วยให้นักพัฒนาซอฟต์แวร์แก้ไขข้อบกพร่องโค้ดที่ใช้องค์ประกอบเลเยอร์บนสุดได้ง่ายขึ้น
บทความนี้อธิบายว่าองค์ประกอบเลเยอร์บนสุดคืออะไร เครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ช่วยแสดงเนื้อหาเลเยอร์บนสุดเป็นภาพได้อย่างไรเพื่อให้เข้าใจและแก้ไขข้อบกพร่องของโครงสร้าง DOM ที่มีองค์ประกอบเลเยอร์บนสุด และวิธีใช้การรองรับเลเยอร์บนสุดของเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์
เลเยอร์บนสุดและองค์ประกอบเลเยอร์บนสุดคืออะไร
เกิดอะไรขึ้นบ้างภายในเมื่อคุณเปิด <dialog>
เป็นโมดอล 🤔
ข้อความจะอยู่ในเลเยอร์บนสุด เนื้อหาเลเยอร์บนสุดจะแสดงผลบนเนื้อหาอื่นๆ ทั้งหมด เช่น กล่องโต้ตอบแบบโมดัลต้องปรากฏที่ด้านบนของเนื้อหา DOM อื่นๆ ทั้งหมด ดังนั้นเบราว์เซอร์จะแสดงผลองค์ประกอบนี้ใน "เลเยอร์บนสุด" โดยอัตโนมัติแทนที่จะบังคับให้ผู้เขียนต้องจัดการกับ z-index ด้วยตนเอง องค์ประกอบเลเยอร์บนสุดจะปรากฏที่ด้านบนขององค์ประกอบแม้จะมีค่า z-index สูงสุดก็ตาม
เลเยอร์บนสุดอาจอธิบายได้ว่าเป็น "เลเยอร์การจัดวางที่สูงที่สุด" เอกสารแต่ละรายการมีวิวพอร์ตที่เชื่อมโยงกันรายการเดียว จึงมีเลเยอร์บนสุดรายการเดียวด้วย องค์ประกอบหลายรายการจะอยู่ภายในเลเยอร์บนสุดพร้อมกันได้ เมื่อเกิดกรณีนี้ขึ้น รายการจะซ้อนกัน โดยรายการล่าสุดจะอยู่ด้านบน กล่าวคือ องค์ประกอบของเลเยอร์บนสุดทั้งหมดจะอยู่ในกองเข้าก่อนออกก่อน (LIFO) ในเลเยอร์บนสุด
องค์ประกอบ <dialog>
ไม่ใช่องค์ประกอบเดียวที่เบราว์เซอร์แสดงผลเป็นเลเยอร์บนสุด ปัจจุบันองค์ประกอบเลเยอร์บนสุด ได้แก่ ป๊อปอัป กล่องโต้ตอบแบบโมดอล และองค์ประกอบในโหมดเต็มหน้าจอ
ตรวจสอบการใช้งานกล่องโต้ตอบต่อไปนี้
<main>
<button onclick="window.dialog.showModal();">Open Dialog</button>
</main>
<dialog id="dialog"></dialog>
ต่อไปนี้เป็นตัวอย่างกล่องโต้ตอบ 2 รายการที่มีการใช้สไตล์กับพื้นหลัง (พื้นหลังอธิบายไว้ด้านล่าง)
พื้นหลังคืออะไร
แต่โชคดีที่ยังมีวิธีปรับแต่งเนื้อหาที่อยู่ใต้องค์ประกอบเลเยอร์บนสุด
องค์ประกอบทุกรายการในเลเยอร์บนสุดจะมีองค์ประกอบจำลอง 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
ระบบจะนำคลาสนี้ออกเมื่อนำองค์ประกอบออกจากเลเยอร์บนสุด
ดูโค้ดในตัวอย่างเดโมนี้
การออกแบบการสนับสนุนเลเยอร์บนสุดในเครื่องมือสำหรับนักพัฒนาเว็บ
การรองรับเลเยอร์บนสุดของ DevTools ช่วยให้นักพัฒนาแอปเข้าใจแนวคิดของเลเยอร์บนสุดและเห็นภาพว่าเนื้อหาเลเยอร์บนสุดเปลี่ยนแปลงไปอย่างไร ฟีเจอร์เหล่านี้ช่วยให้นักพัฒนาแอประบุสิ่งต่อไปนี้ได้
- องค์ประกอบในเลเยอร์บนสุดและลําดับขององค์ประกอบนั้นๆ ได้ทุกเมื่อ
- องค์ประกอบที่ด้านบนของกองซ้อน ณ เวลาใดก็ได้
นอกจากนี้ การรองรับเลเยอร์บนสุดของ DevTools ยังช่วยให้เห็นภาพตําแหน่งองค์ประกอบเสมือนพื้นหลังในกองเลเยอร์บนสุด แม้ว่าจะไม่ใช่องค์ประกอบต้นไม้ แต่ก็มีบทบาทสำคัญในวิธีการทำงานของเลเยอร์บนสุดและเป็นประโยชน์ต่อนักพัฒนาซอฟต์แวร์
ฟีเจอร์การสนับสนุนเลเยอร์บนสุดช่วยให้คุณทำสิ่งต่อไปนี้ได้
- สังเกตองค์ประกอบที่อยู่ในกองเลเยอร์บนสุดได้ทุกเมื่อ กองการแสดงผลของเลเยอร์บนสุดจะเปลี่ยนแปลงแบบไดนามิกเมื่อมีการเพิ่มหรือนำองค์ประกอบออกจากเลเยอร์บนสุด
- ดูตำแหน่งองค์ประกอบในกองเลเยอร์ด้านบน
- ข้ามจากองค์ประกอบเลเยอร์บนหรือองค์ประกอบจำลองฉากหลังในต้นไม้ไปยังองค์ประกอบหรือองค์ประกอบจำลองฉากหลังในคอนเทนเนอร์การแสดงผลเลเยอร์บนและกลับ
มาดูวิธีใช้ฟีเจอร์เหล่านี้กัน
คอนเทนเนอร์เลเยอร์บน
เครื่องมือสำหรับนักพัฒนาซอฟต์แวร์จะเพิ่มคอนเทนเนอร์เลเยอร์บนสุดลงในโครงสร้างองค์ประกอบเพื่อช่วยให้เห็นภาพองค์ประกอบเลเยอร์บนสุด อยู่หลังแท็ก </html>
ที่ปิด
คอนเทนเนอร์นี้ช่วยให้คุณสังเกตองค์ประกอบในกองเลเยอร์ด้านบนได้ทุกเมื่อ คอนเทนเนอร์เลเยอร์บนสุดคือรายการลิงก์ไปยังองค์ประกอบเลเยอร์บนสุดและพื้นหลังขององค์ประกอบเหล่านั้น กองการแสดงผลของเลเยอร์บนสุดจะเปลี่ยนแปลงแบบไดนามิกเมื่อมีการเพิ่มหรือนำองค์ประกอบออกจากเลเยอร์บนสุด
หากต้องการค้นหาองค์ประกอบของเลเยอร์บนสุดภายในลําดับชั้นองค์ประกอบหรือคอนเทนเนอร์ของเลเยอร์บนสุด ให้คลิกลิงก์จากการแสดงองค์ประกอบของเลเยอร์บนสุดในคอนเทนเนอร์ของเลเยอร์บนสุดไปยังองค์ประกอบเดียวกันในลําดับชั้นองค์ประกอบและกลับ
หากต้องการข้ามจากองค์ประกอบคอนเทนเนอร์ของเลเยอร์บนสุดไปยังองค์ประกอบต้นไม้ของเลเยอร์บนสุด ให้คลิกปุ่มแสดงข้างองค์ประกอบในคอนเทนเนอร์ของเลเยอร์บนสุด
หากต้องการข้ามจากองค์ประกอบต้นไม้ของเลเยอร์บนสุดไปยังลิงก์ในคอนเทนเนอร์ของเลเยอร์บนสุด ให้คลิกป้ายเลเยอร์บนสุดข้างองค์ประกอบ
คุณปิดป้ายใดก็ได้ รวมถึงป้ายระดับบนสุด หากต้องการปิดใช้ป้าย ให้คลิกขวาที่ป้ายใดก็ได้ แล้วเลือกการตั้งค่าป้าย จากนั้นยกเลิกการเลือกข้างป้ายที่ต้องการซ่อน
ลําดับองค์ประกอบในกองเลเยอร์ด้านบน
คอนเทนเนอร์เลเยอร์บนสุดจะแสดงองค์ประกอบตามที่ปรากฏในกอง แต่กลับลำดับ องค์ประกอบที่ซ้อนกันอยู่ด้านบนสุดจะเป็นรายการสุดท้ายในรายการองค์ประกอบของคอนเทนเนอร์เลเยอร์บนสุด ซึ่งหมายความว่าองค์ประกอบสุดท้ายในรายการคอนเทนเนอร์ของเลเยอร์บนสุดคือองค์ประกอบที่คุณโต้ตอบกับได้ในเอกสารในขณะนี้
ป้ายข้างองค์ประกอบต้นไม้จะระบุว่าองค์ประกอบนั้นอยู่ในเลเยอร์บนสุดหรือไม่ และมีหมายเลขตำแหน่งขององค์ประกอบในกอง
ในภาพหน้าจอนี้ สแต็กเลเยอร์ด้านบนประกอบด้วยองค์ประกอบ 2 รายการ โดยมีองค์ประกอบที่ 2 อยู่ด้านบนสุดของสแต็ก หากคุณนําองค์ประกอบที่ 2 ออก องค์ประกอบแรกจะย้ายไปอยู่ด้านบน
พื้นหลังในคอนเทนเนอร์เลเยอร์บนสุด
ดังที่กล่าวไว้ข้างต้น องค์ประกอบเลเยอร์บนสุดทุกรายการมีพร็อพเพอร์ตี้เสมือน CSS ที่เรียกว่า "พื้นหลัง" คุณจัดสไตล์องค์ประกอบนี้ได้ จึงควรตรวจสอบและดูการแสดงผลขององค์ประกอบด้วย
ในทรีองค์ประกอบ องค์ประกอบฉากหลังจะอยู่ก่อนแท็กปิดขององค์ประกอบที่เป็นองค์ประกอบของฉากหลัง อย่างไรก็ตาม ในคอนเทนเนอร์เลเยอร์บนสุด ลิงก์พื้นหลังจะแสดงอยู่เหนือองค์ประกอบเลเยอร์บนสุดที่เป็นของลิงก์นั้น
การเปลี่ยนแปลงในแผนผัง DOM
ElementsTreeElement
ซึ่งเป็นคลาสที่รับผิดชอบในการสร้างและจัดการองค์ประกอบของต้นไม้ DOM แต่ละรายการในเครื่องมือสำหรับนักพัฒนาเว็บไม่เพียงพอที่จะใช้คอนเทนเนอร์ชั้นบนสุด
หากต้องการแสดงคอนเทนเนอร์เลเยอร์บนสุดเป็นโหนดในต้นไม้ เราได้เพิ่มคลาสใหม่ที่สร้างโหนดองค์ประกอบต้นไม้ของ 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 ทำหน้าที่เป็นโปรโตคอลการสื่อสารระหว่างเครื่องมือสำหรับนักพัฒนาเว็บกับ 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
หากต้องการดูรายการองค์ประกอบชั้นบนสุดที่เป็นปัจจุบัน เราจําเป็นต้องให้การเปลี่ยนแปลงองค์ประกอบชั้นบนสุดทั้งหมดทริกเกอร์เหตุการณ์ CDP เวอร์ชันทดลอง เหตุการณ์นี้จะแจ้งให้ส่วนหน้าทราบถึงการเปลี่ยนแปลง จากนั้นจะเรียกใช้คําสั่ง DOM.getTopLayerElements
และรับรายการองค์ประกอบใหม่
เหตุการณ์มีลักษณะดังนี้
# Called by the change of the top layer elements.
experimental event topLayerElementsUpdated
ข้อควรพิจารณาเกี่ยวกับ CDP
การติดตั้งใช้งานการรองรับ CDP ของเลเยอร์บนสุดมีหลายวิธี อีกตัวเลือกหนึ่งที่เราพิจารณาคือการสร้างเหตุการณ์ที่จะแสดงรายการองค์ประกอบเลเยอร์บนสุดแทนที่จะแจ้งให้ส่วนหน้าทราบเกี่ยวกับการเพิ่มหรือนําองค์ประกอบเลเยอร์บนสุดออก
หรือจะสร้างเหตุการณ์ 2 รายการแทนคำสั่ง topLayerElementAdded
และ topLayerElementRemoved
ก็ได้ ในกรณีนี้ เราจะได้รับองค์ประกอบและจะต้องจัดการอาร์เรย์ขององค์ประกอบเลเยอร์บนสุดในหน้าเว็บ
ปัจจุบันเหตุการณ์ในหน้าเว็บเรียกใช้คําสั่ง getTopLayerElements
เพื่อรับรายการองค์ประกอบที่อัปเดต หากส่งรายการองค์ประกอบหรือองค์ประกอบที่ทำให้เกิดการเปลี่ยนแปลงทุกครั้งที่ทริกเกอร์เหตุการณ์ เราจะหลีกเลี่ยงการเรียกใช้คําสั่งได้ 1 ขั้นตอน
อย่างไรก็ตาม ในกรณีนี้ ฟีดหน้าเว็บจะควบคุมไม่ได้ว่าระบบจะพุชองค์ประกอบใด
เราใช้วิธีนี้เนื่องจากเราคิดว่าการทำให้ส่วนหน้าตัดสินใจว่าจะขอโหนดชั้นบนเมื่อใดนั้นดีกว่า เช่น หากยุบเลเยอร์ด้านบนใน UI หรือผู้ใช้ใช้แผง DevTools ที่ไม่มีต้นไม้องค์ประกอบ ก็ไม่จำเป็นต้องรับโหนดเพิ่มเติมที่อาจอยู่ลึกลงไปในต้นไม้