开发者工具中新增了滚动标志:更快地找到可滚动元素

Ionuț Marius Voicilă
Ionuț Marius Voicilă

借助 DevTools 的新滚动标记,调试滚动相关问题变得更加轻松!本文介绍了什么是可滚动元素、为什么它们可能很难找到,以及这项新功能如何帮助您快速找到它们。我们还将带您深入幕后,了解滚动标记的开发过程。

“元素”面板中新增了滚动标记。

什么是可滚动元素?

如果您可以滚动元素内的内容,则该元素是可滚动元素(或滚动容器)。滚动条的存在与否无关紧要。

为什么很难找到可滚动元素?

调试滚动问题并不容易。如果没有用于清晰显示可滚动元素的工具,用户很容易迷失,尤其是在没有滚动条的复杂网页上。

手动查找滚动元素可能是一个繁琐的试错过程:

  1. 您可以选择一个元素并修改其样式。
  2. 滚动条是否消失了?如果没有,请重复此过程。

推出滚动标志

在 Chrome 130 中,您可以使用元素面板中的新滚动标记来定位可滚动元素!

“元素”面板中新增了滚动标记。

例如,尝试使用新的滚动标记,找出在以下示例中导致滚动条显示的元素。

新滚动徽章的技术实现

在后台,实现分为两部分:

  • 识别可滚动元素。使用 Blink’s(Chrome 的渲染引擎)信号来识别可滚动或因网页发生变化而变得可滚动的元素。
  • 显示滚动徽章。收到信号后,我们会在 Elements 面板中可滚动元素旁边添加一个新标记(类似于现有的网格标记)。

识别可滚动元素

为了识别可滚动元素,我们在 Blink 中使用了 IsUserScrollable 方法。此方法通过检查节点是否沿 X 轴或 Y 轴溢出来确定节点是否可滚动,这表示内容超出容器尺寸且可滚动。每次在 DevTools 中加载新元素时,我们都会调用此方法来识别可滚动容器。

为了动态更新已加载元素的可滚动状态,我们不得不深入研究 Blink 渲染引擎代码库,以跟踪节点的可滚动区域的添加或移除位置。

用于处理溢出的核心逻辑由 PaintLayerScrollableArea 组件管理。具体而言,UpdateScrollableAreaSet 方法负责检测溢出何时发生或何时已解决。

系统会通过发送更改了 ScrollableArea 的节点的引用,将此信息中继到 DevTools 后端。

然后,后端使用 IsUserScrollable 方法重新检查节点,以获取其新状态。验证可滚动性后,系统会使用 Chrome DevTools Protocol 向前端发送信号,确保界面准确反映可滚动内容的变化。

显示滚动标志

为了在 DevTools 前端添加新标记,我们在 ElementsTreeOutline 中创建了一个处理脚本方法,用于接收通过事件更改其滚动性状态的元素的 nodeId。在该处理脚本中,我们使用 nodeId 检索 ElementsTreeElement 对象,并指示其更新滚动标记。

更新滚动标记需要检查元素是否可滚动以及是否已具有滚动标记。根据这些条件,系统会执行以下操作:

  • 如果元素可滚动且尚无滚动标记,系统会添加一个滚动标记。
  • 如果元素不可滚动,但具有滚动标记,系统会移除现有标记。

用于处理可滚动顶级文档的特殊逻辑

当顶级文档可滚动时,我们会遇到一个特殊情况,因为我们不会为主要文档显示 #document 元素,只会为 iframe 显示。因此,我们无法直接在 #document 元素上显示徽章

我们决定改为在 </html> 元素上显示滚动标记,包括在 Quirks mode 中显示的标记(其中 document.scrollingElement() 会返回 <body>null)。此决策可防止可滚动文档与可滚动正文元素之间混淆,尤其是在正文可以独立滚动的页面上。

我们发现,这是向开发者展示哪些元素可以滚动的最清晰方式。

“元素”面板中 HTML 标记旁边的滚动标记。

Chrome DevTools Protocol (CDP) 变更

为了集成新的滚动标记,需要对 Chrome DevTools Protocol (CDP) 进行更改。CDP 充当 DevTools 和 Chrome 之间的通信协议。

我们不得不更改协议,以涵盖以下两种情况:

  • 此节点在开发者工具中加载后是否可滚动?
  • 此节点是否更新了其可滚动状态?
此节点在开发者工具中加载后是否可滚动?

我们向 DOM.Node 数据类型添加了一个名为 isScrollable 的新属性,系统会在每次在开发者工具前端加载新节点时发送该属性。

我们决定仅在该属性为 true 时填充此属性,以免加载不必要的数据。因此,如果未发送该属性,我们会假定元素不可滚动。

此节点是否更新了其可滚动状态?

为了检测节点是否更新了其可滚动状态,我们在 CDP 中引入了新事件 scrollableFlagUpdated,每当元素获得或失去可滚动区域时,该事件就会触发。该事件的结构如下:

  # Fired when a node's scrollability state changes.
  experimental event scrollableFlagUpdated
    parameters
      # The id of the node.
      DOM.NodeId nodeId
      # If the node is scrollable.
      boolean isScrollable

专业提示:在浏览器中查看新的 CDP 变更

如果您想了解 Chrome 如何与开发者工具通信,可以通过一种简单的方法进行探索。

借助 Protocol Monitor 面板,您可以查看 Chrome 和 DevTools 之间交换的实时事件,包括为滚动标记新添加的事件。例如,当您修改某个元素的样式而影响其滚动性时,您可以立即看到相关的 CDP 事件。

如需查看更详细的指南,请参阅 Protocol monitor: View and send CDP requests

“元素”面板中新增了滚动标记。

除了滚动之外:推出溢出标记

更棒的是,我们正在开发一个新的溢出标记,以便准确找出滚动的原因。此标记将显示在超出容器的元素旁边,有助于您快速诊断布局问题。

具体运作方式如下:

  • 互动式调试。点击滚动标记可触发 DevTools 协议命令,用于识别溢出的子元素。
  • 直观呈现溢出情况。我们将映射可滚动容器内的元素边界,以检测是否有任何溢出。
  • 突出显示罪魁祸首。溢出标记会标记这些溢出元素,点击该标记会直接在 DOM 中突出显示这些元素。

这将为开发者提供一款强大的新工具,帮助他们了解和解决由内容溢出导致的布局问题。我们相信,这种更深入的分析将显著简化调试工作流程。