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 cho các phần tử lớp trên cùng, giúp nhà phát triển dễ dàng gỡ lỗi hơn mã có sử dụng các phần tử lớp trên cùng.

Bài viết này mô tả về các phần tử lớp trên cùng, 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 và cách triển khai khả năng hỗ trợ lớp trên cùng của Công cụ cho nhà phát triển.

Các 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ì xảy ra nội bộ khi bạn mở <dialog> dưới dạng một phương thức? 🤔

Nó đượ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ụ: hộp thoại phương thức cần xuất hiện trên tất cả nội dung DOM khác, để trình duyệt 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 đấ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 ở trên một phần tử ngay cả với 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 duy nhất được liên kết và do đó cũng là một lớp trên cùng duy nhất. Nhiều phần tử có thể nằm 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 sẽ chồng lên nhau. Nói cách khác, tất cả các phần tử lớp trên cùng được đặt trong một ngăn xếp vào sau, ra trước (LIFO) ở 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 thành 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 phần tử ở chế độ toàn màn hình.

Hãy 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 số hộp thoại 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 là 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 đều 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ể làm mờ, tạo kiểu hoặc ẩn hoàn toàn mọi thứ nằm bên dưới phần tử khi phần tử đó là phần trên cùng trong lớp trên cùng.

Khi bạn tạo nhiều phần tử vào chế độ, trình duyệt sẽ vẽ phông nền ngay dưới phần tử đó ở ngoài cùng và phía 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ó phông nền thuộc về ngăn xếp lớp trên cùng. Những 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%, các phông nền bên dưới có thể nhìn thấy.

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ể đạt được điều này bằng cách theo dõi giá trị nhận dạng mục trong ngăn xếp lớp trên cùng.

Nếu phần tử được thêm không phải là phần tử đầu tiên trong lớp trên cùng, hàm được gọi khi phần tử được đưa vào lớp trên cùng sẽ áp dụng một 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ạ mẫu này:

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

Khả năng hỗ trợ Công cụ cho nhà phát triển 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 của 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 điều sau:

  • Các phần tử ở lớp trên cùng bất cứ lúc nào và thứ tự của các phần tử đó.
  • Phần tử ở đầu ngăn xếp vào bất kỳ lúc 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ả của 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 thành phần dạng cây, nhưng lớp này đóng vai trò quan trọng trong cách hoạt động của lớp trên cùng và có thể hữu ích cho 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 xem 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 thể hiện lớp trên cùng thay đổi linh hoạt 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 phần tử giả phông nền của phần tử trên cây sang phần tử giả phần tử hoặc phông nền trong vùng chứa đại diện cho lớp trên cùng và phía sau.

Hãy cùng 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 một vùng chứa lớp trên cùng vào cây phần tử. Đoạn mã 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 thể hiện lớp trên cùng thay đổi linh hoạt 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ừ cách 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 của 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 của 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 bất kỳ huy hiệu nào, bao gồm 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 huy hiệu bất kỳ, chọn Cài đặt huy hiệu rồi xoá dấu kiểm bên cạnh huy hiệu bạn muốn ẩn.

Đang tắt huy hiệu.

Thứ tự 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 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ử mà 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 liệu các phần tử đó có thuộc về lớp trên cùng hay không và có chứa số vị trí của một phần tử trong ngăn xếp 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ử, trong đó phần tử thứ hai ở trên cùng của ngăn xếp. Nếu bạn xoá phần tử thứ hai, thì phần tử đầu tiên sẽ di 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ể định kiểu cho phần tử này, vì vậy, bạn cũng nên kiểm tra và xem cách biểu diễn của phần tử này.

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, đường liên kết đến 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ý các phần tử cây DOM riêng lẻ 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 tạo các nút phần tử cây Công cụ cho nhà phát triển. Trước đây, lớp chịu trách nhiệm tạo cây thành phần cho Công cụ cho nhà phát triển đã khởi chạy mỗi TreeElement bằng DOMNode, đây là một lớp có backendNodeId và các thuộc tính liên quan đến phần phụ trợ khác. Đến lượt backendNodeId, được gán trên phần phụ trợ.

Nút vùng chứa lớp trên cùng có danh sách đườ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à nút DOM "thực" 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ề phần tử này. Để có hoạt động tương tự như các nút khác, chúng tôi đã 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.

Để có đượ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ành phần đồ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ằ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

Lúc đầ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 tìm nạp các phần tử con hoạt động trong Công cụ cho nhà phát triển. Mỗi phần tử đều có một con trỏ mẹ dùng để 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ả các phần tử con ở nhiều vị trí trong cây. Nói chung, hệ thống không được xây dựng với các cây con trùng lặp.

Hành vi xâm phạm mà chúng tôi đã đi đến là tạo 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 tương tự 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ó một 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 về Giao thức Công cụ của Chrome cho nhà phát triển (CDP)

Để triển khai 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 giao tiếp 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:

  • 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ử của 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 mã nhận dạng 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 các phần tử ở lớp trên cùng thay đổi. Lệnh sẽ 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

Để có danh sách mới nhất về các phần tử của lớp trên cùng, chúng ta cần thực hiện mọi thay đổi với các phần tử của lớp trên cùng để kích hoạt sự kiện CDP thử nghiệm. Sự kiện này thông báo cho giao diện người dùng về thay đổi mà sau đó sẽ 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 hoạt động hỗ trợ CDP cho lớp trên cùng. Một cách khác mà chúng tôi đã xem xét là tạo một sự kiện sẽ trả về danh sách các phần tử của 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 loại bỏ phần tử lớp trên cùng.

Ngoài ra, chúng ta có thể tạo 2 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 gồm các phần tử của lớp trên cùng trên giao diện người dùng.

Hiện tại, một sự kiện giao diện người dùng gọi lệnh getTopLayerElements để lấy danh sách các thành phần đã 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 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 trong việ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 các phần tử được đẩy.

Chúng tôi đã triển khai theo cách này vì theo ý kiến của 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 các 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 không có cây phần tử, thì bạn không cần phải lấy các nút bổ sung có thể nằm sâu hơn trong cây.