เครื่องมือสำหรับนักพัฒนาเว็บใน Chrome กำลังเพิ่มการรองรับองค์ประกอบเลเยอร์ยอดนิยม ซึ่งช่วยให้นักพัฒนาซอฟต์แวร์แก้ไขข้อบกพร่องของโค้ดที่ใช้ประโยชน์จากองค์ประกอบเลเยอร์บนสุดได้ง่ายขึ้น
บทความนี้จะอธิบายว่าองค์ประกอบเลเยอร์บนสุดคืออะไร เครื่องมือสำหรับนักพัฒนาเว็บช่วยให้เห็นภาพเนื้อหาของเลเยอร์ด้านบนเพื่อทำความเข้าใจและแก้ไขข้อบกพร่องของโครงสร้าง DOM ที่มีองค์ประกอบเลเยอร์บนสุด และวิธีนำการรองรับเลเยอร์บนสุดของเครื่องมือสำหรับนักพัฒนาเว็บไปใช้
เลเยอร์ด้านบนและองค์ประกอบเลเยอร์ด้านบนคืออะไร
จะเกิดอะไรขึ้นภายในเมื่อคุณเปิด <dialog>
ขึ้นมาเป็นโมดัล 🤔
โดยวางลงในเลเยอร์บนสุด เนื้อหาเลเยอร์บนสุดจะแสดงทับเนื้อหาอื่นๆ ทั้งหมด ตัวอย่างเช่น กล่องโต้ตอบแบบโมดัลจะต้องปรากฏที่ด้านบนของเนื้อหา DOM อื่นๆ ทั้งหมด ดังนั้นเบราว์เซอร์จะแสดงองค์ประกอบนี้ใน 'เลเยอร์บนสุด' โดยอัตโนมัติ แทนที่จะบังคับให้ผู้เขียนต้องต่อสู้กับดัชนี z ด้วยตนเอง องค์ประกอบเลเยอร์บนสุดจะปรากฏเหนือองค์ประกอบแม้จะมีดัชนี z สูงสุดอยู่ก็ตาม
เลเยอร์ด้านบนอาจหมายถึง "เลเยอร์ที่กองซ้อนสูงสุด" เอกสารแต่ละฉบับมีวิวพอร์ตที่เชื่อมโยงเดียว ดังนั้นจึงมีเลเยอร์บนสุดชั้นเดียว องค์ประกอบหลายรายการสามารถอยู่ภายในเลเยอร์ด้านบนได้พร้อมกัน เมื่อเหตุการณ์นี้เกิดขึ้น องค์ประกอบจะซ้อนกันโดยให้ลำดับสุดท้ายอยู่ด้านบน กล่าวคือ องค์ประกอบเลเยอร์ด้านบนทั้งหมดจะวางอยู่ในสแต็ก last in, first out (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
คลาสนี้จะถูกนำออกเมื่อองค์ประกอบถูกนำออกจากเลเยอร์ด้านบน
ดูโค้ดในการสาธิตตัวอย่างนี้:
การออกแบบการรองรับเลเยอร์บนสุดในเครื่องมือสำหรับนักพัฒนาเว็บ
การรองรับเครื่องมือสำหรับนักพัฒนาเว็บสำหรับเลเยอร์ด้านบนช่วยให้นักพัฒนาซอฟต์แวร์เข้าใจแนวคิดของเลเยอร์ด้านบนและเห็นภาพว่าเนื้อหาของเลเยอร์ด้านบนจะเปลี่ยนแปลงไปอย่างไร ฟีเจอร์เหล่านี้ช่วยให้นักพัฒนาแอประบุข้อมูลต่อไปนี้ได้
- องค์ประกอบในเลเยอร์ด้านบนได้ตลอดเวลาและลำดับขององค์ประกอบ
- องค์ประกอบที่ด้านบนของกลุ่มเมื่อใดก็ได้
นอกจากนี้ การรองรับเลเยอร์ด้านบนของเครื่องมือสำหรับนักพัฒนาเว็บช่วยให้เห็นภาพตำแหน่งขององค์ประกอบเทียมของฉากหลังในกลุ่มเลเยอร์ด้านบน แม้ว่าจะไม่ใช่องค์ประกอบแบบต้นไม้ แต่ก็มีบทบาทสำคัญในวิธีการทำงานของเลเยอร์ด้านบนและมีประโยชน์ต่อนักพัฒนาซอฟต์แวร์
ด้วยฟีเจอร์การรองรับเลเยอร์ด้านบน คุณจะทำสิ่งต่อไปนี้ได้
- คุณสามารถสังเกตองค์ประกอบที่อยู่ในกลุ่มเลเยอร์บนสุดได้ทุกเมื่อ กลุ่มตัวแทนเลเยอร์ด้านบนจะเปลี่ยนแปลงแบบไดนามิกเมื่อมีการเพิ่มหรือนำองค์ประกอบออกจากเลเยอร์ด้านบน
- ดูตำแหน่งขององค์ประกอบในกลุ่มเลเยอร์บนสุด
- ข้ามจากองค์ประกอบเลเยอร์ด้านบนหรือองค์ประกอบของเลเยอร์ด้านบน องค์ประกอบเทียมฉากหลังในต้นไม้ไปยังองค์ประกอบหรือองค์ประกอบเทียมของฉากหลังในคอนเทนเนอร์นำเสนอเลเยอร์บนสุดและด้านหลัง
มาดูวิธีใช้ฟีเจอร์เหล่านี้กัน
คอนเทนเนอร์เลเยอร์บนสุด
เครื่องมือสำหรับนักพัฒนาเว็บจะเพิ่มคอนเทนเนอร์เลเยอร์บนสุดลงในแผนผังองค์ประกอบเพื่อช่วยให้เห็นภาพองค์ประกอบเลเยอร์บนสุด อยู่หลังแท็กปิด </html>
คอนเทนเนอร์นี้ช่วยให้คุณสังเกตองค์ประกอบในกลุ่มเลเยอร์บนสุดได้ทุกเมื่อ คอนเทนเนอร์เลเยอร์บนสุดคือรายการลิงก์ไปยังองค์ประกอบเลเยอร์บนสุดและฉากหลัง กลุ่มตัวแทนเลเยอร์ด้านบนจะเปลี่ยนแปลงแบบไดนามิกเมื่อมีการเพิ่มหรือนำองค์ประกอบออกจากเลเยอร์ด้านบน
หากต้องการค้นหาองค์ประกอบเลเยอร์บนสุดภายในโครงสร้างองค์ประกอบหรือคอนเทนเนอร์ของเลเยอร์บนสุด ให้คลิกลิงก์จากการแสดงองค์ประกอบเลเยอร์บนสุดในคอนเทนเนอร์เลเยอร์บนสุดไปยังองค์ประกอบเดียวกันในโครงสร้างองค์ประกอบและกลับ
หากต้องการข้ามจากองค์ประกอบคอนเทนเนอร์เลเยอร์บนสุดไปยังองค์ประกอบแผนผังเลเยอร์บนสุด ให้คลิกปุ่มแสดงข้างองค์ประกอบในคอนเทนเนอร์เลเยอร์บนสุด
หากต้องการข้ามจากองค์ประกอบแผนผังเลเยอร์บนสุดไปยังลิงก์ในคอนเทนเนอร์เลเยอร์บนสุด ให้คลิกป้ายเลเยอร์บนสุดข้างองค์ประกอบ
คุณสามารถปิดป้ายใดก็ได้ รวมทั้งป้ายเลเยอร์บน เมื่อต้องการปิดใช้ป้าย ให้คลิกขวาที่ป้ายใดก็ได้ เลือกการตั้งค่าป้าย และล้างเครื่องหมายขีดข้างป้ายที่คุณต้องการซ่อน
ลำดับขององค์ประกอบในกลุ่มเลเยอร์บนสุด
คอนเทนเนอร์เลเยอร์บนสุดจะแสดงองค์ประกอบตามที่ปรากฏในกลุ่ม แต่เรียงย้อนกลับในลําดับ ด้านบนขององค์ประกอบกองจะเป็นลำดับสุดท้ายในรายการองค์ประกอบของคอนเทนเนอร์เลเยอร์บนสุด ซึ่งหมายความว่าองค์ประกอบสุดท้ายในรายการคอนเทนเนอร์เลเยอร์บนสุดคือองค์ประกอบที่คุณโต้ตอบด้วยในเอกสารได้ในปัจจุบัน
ป้ายข้างองค์ประกอบแผนผังจะระบุว่าองค์ประกอบดังกล่าวอยู่ในเลเยอร์บนสุดหรือไม่ และมีจำนวนตำแหน่งขององค์ประกอบในกลุ่มนั้นหรือไม่
ในภาพหน้าจอนี้ กลุ่มเลเยอร์ด้านบนประกอบด้วยองค์ประกอบ 2 องค์ประกอบ โดยองค์ประกอบที่ 2 ที่ด้านบนสุดของกลุ่ม หากคุณนำองค์ประกอบที่ 2 ออก องค์ประกอบแรกจะย้ายไปด้านบนสุด
ฉากหลังในคอนเทนเนอร์เลเยอร์บนสุด
ดังที่กล่าวไว้ข้างต้น องค์ประกอบเลเยอร์บนสุดทุกองค์ประกอบมีองค์ประกอบเทียมของ CSS ที่เรียกว่าฉากหลัง คุณจัดรูปแบบองค์ประกอบนี้ได้ การตรวจสอบและดูการนำเสนอจึงเป็นประโยชน์ด้วย
ในแผนผังองค์ประกอบ องค์ประกอบฉากหลังจะอยู่ก่อนแท็กปิดขององค์ประกอบแท็กนั้น อย่างไรก็ตาม ในคอนเทนเนอร์เลเยอร์บนสุด ลิงก์ฉากหลังจะแสดงอยู่เหนือองค์ประกอบของเลเยอร์ระดับบนสุดที่ลิงก์ดังกล่าวอยู่
การเปลี่ยนแปลงของแผนผัง DOM
ElementsTreeElement
ซึ่งเป็นคลาสที่รับผิดชอบในการสร้างและจัดการองค์ประกอบแผนผัง DOM แต่ละรายการในเครื่องมือสำหรับนักพัฒนาเว็บนั้นไม่เพียงพอต่อการใช้งานคอนเทนเนอร์เลเยอร์บนสุด
ในการแสดงคอนเทนเนอร์เลเยอร์บนสุดเป็นโหนดในแผนผัง เราได้เพิ่มคลาสใหม่ที่สร้างโหนดองค์ประกอบแผนผังสำหรับ 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 ของเครื่องมือสำหรับนักพัฒนาเว็บ
การออกแบบเริ่มต้น:
การเปลี่ยนแปลงโปรโตคอลเครื่องมือสำหรับนักพัฒนาเว็บ (CDP) ใน Chrome
หากต้องการใช้การสนับสนุนเลเยอร์บนสุด คุณต้องเปลี่ยนแปลง 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
เพื่อรับรายการองค์ประกอบที่อัปเดต หากเราส่งรายการองค์ประกอบหรือองค์ประกอบที่เจาะจงซึ่งทำให้เกิดการเปลี่ยนแปลงทุกครั้งที่มีการเรียกเหตุการณ์ เราสามารถหลีกเลี่ยงการเรียกใช้คำสั่ง 1 ขั้นตอนได้
อย่างไรก็ตาม ในกรณีนี้ ฟรอนท์เอนด์จะสูญเสียการควบคุมองค์ประกอบที่จะพุช
เรานำวิธีนี้ไปใช้ด้วยวิธีนี้เพราะในความคิดของเรา การตัดสินใจว่าจะขอโหนดเลเยอร์บนสุดจะดีกว่าหากฟรอนท์เอนด์ ตัวอย่างเช่น หากเลเยอร์บนสุดยุบใน UI หรือผู้ใช้แผงเครื่องมือสำหรับนักพัฒนาเว็บที่ไม่มีโครงสร้างองค์ประกอบ ก็ไม่จำเป็นต้องหาโหนดเพิ่มเติมที่อาจลึกลงไปในโครงสร้าง