การรองรับเลเยอร์ระดับบนสุดในเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome

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 ยังช่วยให้เห็นภาพตําแหน่งองค์ประกอบเสมือนพื้นหลังในกองเลเยอร์บนสุด แม้ว่าจะไม่ใช่องค์ประกอบต้นไม้ แต่ก็มีบทบาทสำคัญในวิธีการทำงานของเลเยอร์บนสุดและเป็นประโยชน์ต่อนักพัฒนาซอฟต์แวร์

ฟีเจอร์การสนับสนุนเลเยอร์บนสุดช่วยให้คุณทำสิ่งต่อไปนี้ได้

  1. สังเกตองค์ประกอบที่อยู่ในกองเลเยอร์บนสุดได้ทุกเมื่อ กองการแสดงผลของเลเยอร์บนสุดจะเปลี่ยนแปลงแบบไดนามิกเมื่อมีการเพิ่มหรือนำองค์ประกอบออกจากเลเยอร์บนสุด
  2. ดูตำแหน่งองค์ประกอบในกองเลเยอร์ด้านบน
  3. ข้ามจากองค์ประกอบเลเยอร์บนหรือองค์ประกอบจำลองฉากหลังในต้นไม้ไปยังองค์ประกอบหรือองค์ประกอบจำลองฉากหลังในคอนเทนเนอร์การแสดงผลเลเยอร์บนและกลับ

มาดูวิธีใช้ฟีเจอร์เหล่านี้กัน

คอนเทนเนอร์เลเยอร์บน

เครื่องมือสำหรับนักพัฒนาซอฟต์แวร์จะเพิ่มคอนเทนเนอร์เลเยอร์บนสุดลงในโครงสร้างองค์ประกอบเพื่อช่วยให้เห็นภาพองค์ประกอบเลเยอร์บนสุด อยู่หลังแท็ก </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 ที่ไม่มีต้นไม้องค์ประกอบ ก็ไม่จำเป็นต้องรับโหนดเพิ่มเติมที่อาจอยู่ลึกลงไปในต้นไม้