Hỗ trợ lớp trên cùng trong Công cụ của Chrome cho nhà phát triển

Alina Varkki
Alina Varkki

Công cụ của Chrome cho nhà phát triển sẽ hỗ trợ thêm các phần tử lớp trên cùng, giúp các nhà phát triển dễ dàng gỡ lỗi mã của họ nhờ sử dụng các phần tử lớp trên cùng.

Bài viết này mô tả phần tử lớp trên cùng là gì, cách Công cụ cho nhà phát triển giúp trực quan hoá nội dung lớp trên cùng để hiểu và gỡ lỗi cấu trúc DOM chứa các phần tử lớp trên cùng cũng như cách triển khai hỗ trợ lớp trên cùng của Công cụ cho nhà phát triển.

Phần tử lớp trên cùng và lớp trên cùng là gì?

Chính xác thì điều gì sẽ xảy ra nội bộ khi bạn mở <dialog> làm phương thức? 🤔

Lớp này được đặt vào lớp trên cùng. Nội dung lớp trên cùng hiển thị ở trên tất cả nội dung khác. Ví dụ: một hộp thoại phương thức cần xuất hiện bên trên tất cả nội dung DOM khác, vì vậy trình duyệt sẽ tự động hiển thị phần tử này trong 'lớp trên cùng' thay vì buộc tác giả phải chiến đấu với chỉ mục z theo cách thủ công. Phần tử lớp trên cùng xuất hiện ở đầu một phần tử ngay cả khi có chỉ mục z cao nhất.

Lớp trên cùng có thể được mô tả là "lớp xếp chồng cao nhất". Mỗi tài liệu có một khung nhìn được liên kết và do đó cũng có một lớp trên cùng. Nhiều phần tử có thể ở bên trong lớp trên cùng cùng một lúc. Khi điều đó xảy ra, chúng xếp chồng lên nhau, thành phần cuối cùng ở trên cùng. Nói cách khác, tất cả các phần tử lớp trên cùng được đặt trong ngăn xếp vào sau, ra trước (LIFO) trong lớp trên cùng.

Phần tử <dialog> không phải là phần tử duy nhất mà trình duyệt kết xuất trong lớp trên cùng. Hiện tại, các phần tử lớp trên cùng là: cửa sổ bật lên, hộp thoại phương thức và các thành phần ở chế độ toàn màn hình.

Kiểm tra cách triển khai hộp thoại sau đây:

<main>
  <button onclick="window.dialog.showModal();">Open Dialog</button>
</main>
<dialog id="dialog"></dialog>

Dưới đây là bản minh hoạ với một vài hộp thoại có các kiểu được áp dụng cho phông nền (phông nền được mô tả bên dưới):

Phông nền là gì?

May mắn thay, có một cách tuỳ chỉnh nội dung bên dưới phần tử lớp trên cùng.

Mỗi phần tử trong lớp trên cùng có một phần tử giả CSS được gọi là phông nền.

Phông nền là một hộp có kích thước của khung nhìn được hiển thị ngay bên dưới bất kỳ phần tử lớp trên cùng nào. Phần tử giả ::backdrop giúp bạn có thể che khuất, tạo kiểu hoặc ẩn hoàn toàn mọi thứ nằm bên dưới phần tử khi đó là phần tử trên cùng ở lớp trên cùng.

Khi bạn tạo chế độ cho nhiều phần tử, trình duyệt sẽ vẽ phông nền ngay bên dưới phần tử ở ngoài cùng và trên các phần tử toàn màn hình khác.

Dưới đây là cách bạn tạo kiểu cho phông nền:

/* The browser displays the backdrop only when the dialog.showModal() function opens the dialog.*/
dialog::backdrop {
    background: rgba(255,0,0,.25);
}

Làm cách nào để chỉ hiển thị phông nền đầu tiên?

Mỗi phần tử lớp trên cùng đều có một phông nền thuộc ngăn xếp lớp trên cùng. Các phông nền này được thiết kế để chồng lên nhau, vì vậy nếu độ mờ của phông nền không phải là 100%, bạn có thể nhìn thấy các phông nền bên dưới.

Nếu chỉ cần hiển thị phông nền đầu tiên trong ngăn xếp lớp trên cùng, bạn có thể làm việc này bằng cách theo dõi mã nhận dạng mục trong ngăn xếp lớp trên cùng.

Nếu phần tử đã thêm không phải là phần tử đầu tiên ở lớp trên cùng, thì hàm được gọi khi phần tử được đưa vào lớp trên cùng sẽ áp dụng lớp hiddenBackdrop cho ::backdrop. Lớp này sẽ bị xoá khi phần tử bị xoá khỏi lớp trên cùng.

Hãy xem mã trong bản minh hoạ ví dụ sau:

Thiết kế hỗ trợ lớp trên cùng trong Công cụ cho nhà phát triển

Việc hỗ trợ Công cụ cho lớp trên cùng giúp nhà phát triển hiểu khái niệm về lớp trên cùng và trực quan hoá cách nội dung lớp trên cùng thay đổi. Những tính năng này giúp nhà phát triển xác định những yếu tố sau:

  • Các phần tử trong lớp trên cùng bất cứ lúc nào và thứ tự của chúng.
  • Phần tử ở đầu ngăn xếp tại bất kỳ thời điểm nào.

Hơn nữa, tính năng hỗ trợ lớp trên cùng của Công cụ cho nhà phát triển giúp trực quan hoá vị trí của phần tử giả phông nền trong ngăn xếp lớp trên cùng. Mặc dù không phải là một phần tử cây, nhưng nó đóng vai trò quan trọng trong cách lớp trên cùng hoạt động và có thể hữu ích cho các nhà phát triển.

Với các tính năng hỗ trợ lớp trên cùng, bạn có thể:

  1. Quan sát các phần tử nào nằm trong ngăn xếp lớp trên cùng bất cứ lúc nào. Ngăn xếp biểu diễn lớp trên cùng thay đổi linh động khi các phần tử được thêm vào hoặc bị xoá khỏi lớp trên cùng.
  2. Xem vị trí phần tử trong ngăn xếp lớp trên cùng.
  3. Chuyển từ phần tử lớp trên cùng hoặc các phần tử phần tử giả phông nền trong cây với phần tử hoặc phần tử giả phông nền trong vùng chứa biểu diễn lớp trên cùng và quay lại.

Hãy xem cách sử dụng các tính năng này!

Vùng chứa lớp trên cùng

Để giúp trực quan hoá các phần tử lớp trên cùng, Công cụ cho nhà phát triển thêm vùng chứa lớp trên cùng vào cây phần tử. Phần phụ thuộc này nằm sau thẻ đóng </html>.

Vùng chứa này cho phép bạn quan sát các phần tử trong ngăn xếp lớp trên cùng bất cứ lúc nào. Vùng chứa lớp trên cùng là danh sách các đường liên kết đến các phần tử lớp trên cùng và phông nền của các phần tử đó. Ngăn xếp biểu diễn lớp trên cùng thay đổi linh động khi các phần tử được thêm vào hoặc bị xoá khỏi lớp trên cùng.

Để tìm các phần tử lớp trên cùng trong cây phần tử hoặc vùng chứa lớp trên cùng, hãy nhấp vào các đường liên kết từ phần biểu diễn phần tử lớp trên cùng trong vùng chứa lớp trên cùng đến cùng phần tử trong cây phần tử và phía sau.

Để chuyển từ phần tử vùng chứa lớp trên cùng sang phần tử cây lớp trên cùng, hãy nhấp vào nút hiển thị bên cạnh phần tử trong vùng chứa lớp trên cùng.

Chuyển từ đường liên kết vùng chứa lớp trên cùng đến phần tử.

Để chuyển từ phần tử cây lớp trên cùng sang đường liên kết trong vùng chứa lớp trên cùng, hãy nhấp vào huy hiệu lớp trên cùng bên cạnh phần tử đó.

Chuyển từ một phần t��� sang đường liên kết vùng chứa lớp trên cùng.

Bạn có thể tắt mọi huy hiệu, kể cả huy hiệu lớp trên cùng. Để tắt huy hiệu, hãy nhấp chuột phải vào một huy hiệu bất kỳ, chọn Cài đặt huy hiệu rồi xoá dấu đánh dấu bên cạnh huy hiệu bạn muốn ẩn.

Đang tắt huy hiệu.

Thứ tự các phần tử trong ngăn xếp lớp trên cùng

Vùng chứa lớp trên cùng hiển thị các phần tử khi chúng xuất hiện trong ngăn xếp nhưng theo thứ tự đảo ngược. Phần tử trên cùng của phần tử ngăn xếp là phần tử cuối cùng trong danh sách phần tử của vùng chứa lớp trên cùng. Điều này có nghĩa là phần tử cuối cùng trong danh sách vùng chứa lớp trên cùng là phần tử bạn hiện có thể tương tác trong tài liệu.

Các huy hiệu bên cạnh các phần tử cây cho biết các phần tử đó có thuộc lớp trên cùng và chứa số vị trí của một phần tử trong nhóm ảnh hay không.

Trong ảnh chụp màn hình này, ngăn xếp lớp trên cùng bao gồm hai phần tử, với phần tử thứ hai nằm ở đầu ngăn xếp. Nếu bạn xoá phần tử thứ hai thì phần tử đầu tiên sẽ chuyển lên trên cùng.

Thứ tự của các phần tử trong ngăn xếp.

Phông nền trong vùng chứa lớp trên cùng

Như đã đề c��p ở trên, m��i phần tử lớp trên cùng đều có một phần tử giả CSS được gọi là phông nền. Bạn có thể tạo kiểu cho phần tử này, vì vậy, bạn cũng nên kiểm tra và xem cách trình bày của phần tử đó.

Trong cây phần tử, một phần tử phông nền nằm trước thẻ đóng của phần tử chứa phần tử đó. Tuy nhiên, trong vùng chứa lớp trên cùng, liên kết phông nền được liệt kê ngay phía trên phần tử lớp trên cùng mà nó thuộc về.

Vị trí ngăn xếp phông nền.

Các thay đổi đối với cây DOM

ElementsTreeElement (lớp chịu trách nhiệm tạo và quản lý từng phần tử cây DOM trong Công cụ cho nhà phát triển) không đủ để triển khai vùng chứa lớp trên cùng.

Để hiển thị vùng chứa lớp trên cùng dưới dạng một nút trong cây, chúng tôi đã thêm một lớp mới giúp tạo các nút phần tử cây cho Công cụ cho nhà phát triển. Trước đây, lớp chịu trách nhiệm tạo cây phần tử Công cụ cho nhà phát triển được khởi tạo mỗi TreeElement bằng DOMNode. Đây là lớp có backendNodeId và các thuộc tính liên quan đến phụ trợ khác. Đổi lại, backendNodeId được chỉ định cho phần phụ trợ.

Nút vùng chứa lớp trên cùng có danh sách các đường liên kết đến các phần tử lớp trên cùng, cần hoạt động như một nút phần tử cây thông thường. Tuy nhiên, nút này không phải là một nút 'thực' Nút DOM và phần phụ trợ không cần tạo nút vùng chứa lớp trên cùng.

Để tạo một nút giao diện người dùng đại diện cho lớp trên cùng, chúng ta đã thêm một loại nút giao diện người dùng mới được tạo mà không có DOMNode. Phần tử vùng chứa lớp trên cùng này là nút giao diện người dùng đầu tiên không có DOMNode, nghĩa là nút này chỉ tồn tại trên giao diện người dùng và phần phụ trợ không "biết" về ứng dụng đó. Để có hành vi giống như các nút khác, chúng ta đã tạo một lớp TopLayerContainer mới mở rộng lớp UI.TreeOutline.TreeElement chịu trách nhiệm về hành vi của các nút giao diện người dùng.

Để đạt được vị trí mong muốn, lớp kết xuất một phần tử sẽ đính kèm TopLayerContainer làm thẻ đồng cấp tiếp theo của thẻ <html>.

Huy hiệu lớp trên cùng mới cho biết phần tử này nằm ở lớp trên cùng và đóng vai trò là đường liên kết đến lối tắt của phần tử này trong phần tử TopLayerContainer.

Thiết kế ban đầu

Ban đầu, kế hoạch là sao chép các phần tử lớp trên cùng vào vùng chứa lớp trên cùng thay vì tạo danh sách đường liên kết đến các phần tử. Chúng tôi không triển khai giải pháp này do cách hoạt động của quá trình tìm nạp phần tử con của phần tử trong Công cụ cho nhà phát triển. Mỗi phần tử có một con trỏ mẹ dùng khi tìm nạp phần tử con và không thể có nhiều con trỏ. Do đó, chúng ta không thể có một nút mở rộng đúng cách và chứa tất cả phần tử con ở nhiều vị trí trong cây. Nhìn chung, hệ thống không được xây dựng với các cây con trùng lặp.

Sự xâm phạm mà chúng tôi đạt được là tạo các liên kết đến các nút DOM giao diện người dùng thay vì sao chép các nút đó. Lớp chịu trách nhiệm tạo đường liên kết đến các phần tử trong Công cụ cho nhà phát triển là ShortcutTreeElement, lớp này mở rộng UI.TreeOutline.TreeElement. ShortcutTreeElement có hành vi giống như các phần tử cây DOM khác của Công cụ cho nhà phát triển nhưng không có nút tương ứng trên phần phụ trợ và có nút liên kết đến ElementsTreeElement. Mỗi ShortcutTreeElement đến nút lớp trên cùng có một ShortcutTreeElement con liên kết đến nội dung đại diện của một phần tử giả ::backdrop trong cây DOM của Công cụ cho nhà phát triển.

Thiết kế ban đầu:

Thiết kế ban đầu.

Các thay đổi đối với Giao thức Công cụ của Chrome cho nhà phát triển (CDP)

Để triển khai tính năng hỗ trợ lớp trên cùng, bạn cần phải thay đổi Giao thức Công cụ của Chrome cho nhà phát triển (CDP). CDP đóng vai trò là giao thức liên lạc giữa Công cụ cho nhà phát triển và Chromium.

Chúng ta cần thêm những thành phần sau:

  • Một lệnh để gọi từ giao diện người dùng bất cứ lúc nào.
  • Một sự kiện để kích hoạt trên giao diện người dùng từ phía phụ trợ.

CDP: Lệnh DOM.getTopLayerElements

Để hiển thị các phần tử lớp trên cùng hiện tại, chúng ta cần một lệnh CDP thử nghiệm mới trả về danh sách ID nút của các phần tử nằm trong lớp trên cùng. Công cụ cho nhà phát triển gọi lệnh này bất cứ khi nào Công cụ cho nhà phát triển được mở hoặc khi phần tử lớp trên cùng thay đổi. Lệnh có dạng như sau:

  # 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 sự kiện

Để nhận danh sách mới nhất về các phần tử lớp trên cùng, chúng tôi cần mọi thay đổi của các phần tử lớp trên cùng để kích hoạt sự kiện CDP thử nghiệm. Sự kiện này sẽ thông báo cho giao diện người dùng về thay đổi, sau đó gọi lệnh DOM.getTopLayerElements và nhận danh sách phần tử mới.

Sự kiện sẽ có dạng như sau:

  # Called by the change of the top layer elements.
  experimental event topLayerElementsUpdated

Những điểm cần lưu ý về CDP

Có nhiều lựa chọn về cách triển khai hỗ trợ CDP của lớp trên cùng. Một lựa chọn khác mà chúng tôi đã cân nhắc là tạo một sự kiện sẽ trả về danh sách các phần tử lớp trên cùng thay vì chỉ thông báo cho giao diện người dùng về việc thêm hoặc xoá phần tử lớp trên cùng.

Ngoài ra, chúng ta có thể tạo hai sự kiện thay vì lệnh: topLayerElementAddedtopLayerElementRemoved. Trong trường hợp này, chúng ta sẽ nhận được một phần tử và cần phải quản lý mảng các phần tử lớp trên cùng ở giao diện người dùng.

Hiện tại, sự kiện giao diện người dùng gọi lệnh getTopLayerElements để lấy danh sách các phần tử đã cập nhật. Nếu gửi danh sách các phần tử hoặc một phần tử cụ thể gây ra sự thay đổi mỗi khi một sự kiện được kích hoạt, chúng ta có thể tránh được một bước gọi lệnh. Tuy nhiên, trong trường hợp này, giao diện người dùng sẽ mất quyền kiểm soát phần tử nào được đẩy.

Chúng ta đã triển khai theo cách này vì theo chúng tôi, sẽ tốt hơn nếu giao diện người dùng quyết định thời điểm yêu cầu nút lớp trên cùng. Ví dụ: nếu lớp trên cùng được thu gọn trong giao diện người dùng hoặc người dùng đang sử dụng bảng điều khiển Công cụ cho nhà phát triển mà không có cây phần tử, thì bạn không cần tải các nút bổ sung có thể nằm sâu hơn trong cây.