เครื่องมือสำหรับนักพัฒนาเว็บใน Chrome กำลังเพิ่มการรองรับองค์ประกอบเลเยอร์บนสุด ซึ่งทำให้นักพัฒนาซอฟต์แวร์แก้ไขข้อบกพร่องของโค้ดที่ใช้ประโยชน์จากองค์ประกอบเลเยอร์บนสุดได้ง่ายขึ้น
บทความนี้อธิบายถึงองค์ประกอบของเลเยอร์บนสุด, วิธีที่เครื่องมือสำหรับนักพัฒนาเว็บช่วยให้เห็นภาพเนื้อหาของเลเยอร์บนสุดเพื่อทําความเข้าใจและแก้ไขข้อบกพร่องของโครงสร้าง DOM ที่มีองค์ประกอบของเลเยอร์ระดับบนสุด และวิธีใช้การรองรับเลเยอร์บนสุดของเครื่องมือสําหรับนักพัฒนาเว็บ
เลเยอร์บนสุดและองค์ประกอบของเลเยอร์บนสุดคืออะไร
จะเกิดอะไรขึ้นภายในบ้างเมื่อคุณเปิด <dialog>
เป็นโมดัล 🤔
และใส่ลงไปในชั้นบนสุด เนื้อหาเลเยอร์ด้านบนจะแสดงทับเนื้อหาอื่นๆ ทั้งหมด ตัวอย่างเช่น กล่องโต้ตอบโมดัลต้องปรากฏที่ด้านบนของเนื้อหา DOM อื่นๆ ทั้งหมด เบราว์เซอร์จึงแสดงผลองค์ประกอบนี้ใน 'เลเยอร์บนสุด' โดยอัตโนมัติแทนการบังคับให้ผู้เขียนต่อสู้ด้วยดัชนี z ด้วยตนเอง องค์ประกอบเลเยอร์บนสุดจะปรากฏที่ด้านบนขององค์ประกอบหนึ่งแม้ว่าจะมีดัชนีลำดับ z สูงสุดก็ตาม
เลเยอร์บนสุดอาจอธิบายได้ว่าเป็น "เลเยอร์ซ้อนสูงสุด" เอกสารแต่ละฉบับมีวิวพอร์ตที่เชื่อมโยงกัน 1 ชั้น จึงเป็นเลเยอร์บนสุดชั้นเดียวด้วย องค์ประกอบหลายรายการสามารถอยู่ในเลเยอร์บนสุดพร้อมกันได้ เมื่อเกิดกรณีนี้ขึ้น แหล่งที่มาจะซ้อนกัน แถวสุดท้ายจะอยู่ด้านบน กล่าวคือ องค์ประกอบเลเยอร์บนสุดทั้งหมดจะอยู่ในกลุ่มสุดท้ายเข้า ออกก่อน (LIFO) ในเลเยอร์บนสุด
องค์ประกอบ <dialog>
ไม่ใช่องค์ประกอบเดียวที่เบราว์เซอร์แสดงผลในเลเยอร์บนสุด ปัจจุบันองค์ประกอบของเลเยอร์ด้านบน ได้แก่
ป๊อปอัป กล่องโต้ตอบโมดัล และองค์ประกอบในโหมดเต็มหน้าจอ
ตรวจสอบการใช้งานกล่องโต้ตอบต่อไปนี้
<main>
<button onclick="window.dialog.showModal();">Open Dialog</button>
</main>
<dialog id="dialog"></dialog>
นี่เป็นการสาธิตที่มีกล่องโต้ตอบ 2-3 กล่องโต้ตอบที่มีการใช้รูปแบบกับฉากหลัง (ฉากหลังอธิบายไว้ด้านล่าง)
ฉากหลังคืออะไร
โชคดีที่มีวิธีปรับแต่งเนื้อหาที่อยู่ใต้องค์ประกอบเลเยอร์บนสุด
ทุกองค์ประกอบในเลเยอร์บนสุดจะมีองค์ประกอบเทียม 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>
คอนเทนเนอร์นี้ช่วยให้คุณสังเกตองค์ประกอบในกลุ่มเลเยอร์บนสุดได้ทุกเมื่อ คอนเทนเนอร์เลเยอร์บนสุดคือรายการลิงก์ไปยังองค์ประกอบเลเยอร์บนสุดและฉากหลัง กลุ่มการแสดงเลเยอร์บนสุดจะเปลี่ยนแปลงแบบไดนามิกเมื่อมีการเพิ่มหรือนำองค์ประกอบออกจากเลเยอร์บนสุด
หากต้องการค้นหาองค์ประกอบเลเยอร์บนสุดภายในแผนผังองค์ประกอบหรือคอนเทนเนอร์เลเยอร์บนสุด ให้คลิกลิงก์จากการแสดงองค์ประกอบเลเยอร์บนสุดในคอนเทนเนอร์เลเยอร์บนสุดไปยังองค์ประกอบเดียวกันในแผนผังองค์ประกอบและกลับ
หากต้องการข้ามจากองค์ประกอบคอนเทนเนอร์เลเยอร์บนสุดไปยังองค์ประกอบโครงสร้างเลเยอร์บนสุด ให้คลิกปุ่มแสดงข้างองค์ประกอบในคอนเทนเนอร์เลเยอร์บนสุด
หากต้องการข้ามจากองค์ประกอบแผนผังเลเยอร์บนสุดไปยังลิงก์ในคอนเทนเนอร์เลเยอร์บนสุด ให้คลิกป้ายเลเยอร์บนสุดข้างองค์ประกอบนั้น
คุณสามารถปิดป้ายใดก็ได้ รวมถึงป้ายเลเยอร์ด้านบน หากต้องการปิดป้าย ให้คลิกขวาที่ป้ายใดก็ได้ เลือกการตั้งค่าป้าย แล้วลบเครื่องหมายถูกข้างๆ ป้ายที่คุณต้องการซ่อน
ลำดับองค์ประกอบในกลุ่มเลเยอร์บนสุด
คอนเทนเนอร์เลเยอร์บนสุดจะแสดงองค์ประกอบตามที่ปรากฏในกลุ่ม แต่เรียงกลับกัน ด้านบนขององค์ประกอบซ้อนคือองค์ประกอบสุดท้ายในรายการองค์ประกอบของคอนเทนเนอร์เลเยอร์บนสุด ซึ่งหมายความว่าองค์ประกอบสุดท้ายในรายการคอนเทนเนอร์ของเลเยอร์บนสุดคือองค์ประกอบที่คุณโต้ตอบด้วยในเอกสารได้ในปัจจุบัน
ป้ายข้างองค์ประกอบของต้นไม้จะระบุว่าองค์ประกอบนั้นๆ อยู่ในเลเยอร์บนสุดหรือไม่ และมีหมายเลขตำแหน่งขององค์ประกอบในกองซ้อนหรือไม่
ในภาพหน้าจอนี้ กลุ่มเลเยอร์บนสุดประกอบด้วย 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 สำหรับเครื่องมือสำหรับนักพัฒนาเว็บอื่นๆ แต่ไม่มีโหนดที่เกี่ยวข้องในแบ็กเอนด์และมีปุ่มที่ลิงก์ไปยัง ElementsTreeElement
ShortcutTreeElement
แต่ละรายการไปยังโหนดเลเยอร์บนสุดมี ShortcutTreeElement
ย่อยที่ลิงก์ไปยังการแสดงองค์ประกอบจำลอง ::backdrop
ในแผนผัง DOM สำหรับ DevTools
การออกแบบเบื้องต้น
การเปลี่ยนแปลงโปรโตคอลสำหรับนักพัฒนาเว็บใน Chrome (CDP)
คุณต้องเปลี่ยนแปลง Chrome DevTools Protocol (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
เพื่อรับรายการองค์ประกอบที่อัปเดต หากเราส่งรายการองค์ประกอบ หรือองค์ประกอบเฉพาะที่ทำให้เกิดการเปลี่ยนแปลงทุกครั้งที่ทริกเกอร์เหตุการณ์ เราอาจหลีกเลี่ยงการเรียกใช้คำสั่งเพียงขั้นตอนเดียวได้
แต่ในกรณีนี้ ฟรอนท์เอนด์จะเสียสิทธิ์ในการควบคุมว่าจะพุชองค์ประกอบใดบ้าง
เรานำมาใช้ในลักษณะนี้เพราะในความคิดของเราแล้ว จะดีกว่าหากฟรอนท์เอนด์ตัดสินใจว่าเมื่อใดที่จะขอโหนดของเลเยอร์บนสุด ตัวอย่างเช่น ถ้าเลเยอร์บนสุดถูกยุบใน UI หรือผู้ใช้ใช้แผงเครื่องมือสำหรับนักพัฒนาเว็บที่ไม่มีแผนผังองค์ประกอบ ก็ไม่จำเป็นต้องได้รับโหนดเพิ่มเติมที่อาจลึกลงไปในแผนผังได้