Element: getClientRects() 方法

Baseline 已广泛支持

此特性已相当成熟,可在许多设备和浏览器版本上使用。自 ⁨2015 年 7 月⁩以来,各浏览器均已提供此特性。

Element 接口的 getClientRects() 方法返回一个 DOMRect 对象集合,这些对象指示了客户端中每个 CSS 边框盒 的边界矩形。

大多数元素的边框盒都只有一个,但多行的 行内级元素(例如,默认情况下多行的 <span> 元素)的每行都有一个边框盒。

语法

js
getClientRects()

参数

无。

返回值

返回值为一个 DOMRect 对象集合,对应于元素关联的每个 CSS 边框盒。每个 DOMRect 对象以像素为单位描述边框盒,其左上角相对于视口的左上角。对于带标题的表格,即使标题在表格边框盒之外,也会包含该标题。当在 <svg> 元素(外层 <svg> 除外)上调用时,生成的矩形所相对于的“视口”是其外层 <svg> 建立的视口(并且需要明确的是,如果外层 <svg>viewBox 变换,那么矩形也会被该变换变换)。

在计算矩形时会考虑视口区域(或任何其他可滚动元素)的滚动量。

返回的矩形不包含可能溢出的任何子元素的边界。

对于 HTML 的 <area> 元素、不自行渲染的 SVG 元素、display:none 的元素以及通常任何不直接渲染的元素,将返回一个空列表。

即使对于具有空边框盒的 CSS 盒模型,也会返回矩形。lefttoprightbottom 坐标仍然有意义。

可能存在像素偏移的零头数。

示例

这些示例以各种颜色绘制了客户端矩形。请注意,绘制客户端矩形的 JavaScript 函数通过类名 withClientRectsOverlay 与标记连接。

HTML

示例 1:此 HTML 创建了三个带有内部 <span> 的段落,每个段落都包含在一个 <div> 块中。客户端矩形将绘制在第二个块的段落以及第三个块的 <span> 元素的上面。

html
<h3>A paragraph with a span inside</h3>
<p>
  Both the span and the paragraph have a border set. The client rects are in
  red. Note that the p has only one border box, while the span has multiple
  border boxes.
</p>

<div>
  <strong>Original</strong>
  <p>
    <span>Paragraph that spans multiple lines</span>
  </p>
</div>

<div>
  <strong>p's rect</strong>
  <p class="withClientRectsOverlay">
    <span>Paragraph that spans multiple lines</span>
  </p>
</div>

<div>
  <strong>span's rect</strong>
  <p>
    <span class="withClientRectsOverlay"
      >Paragraph that spans multiple lines</span
    >
  </p>
</div>

示例 2:此 HTML 创建了三个有序列表。客户端矩形将绘制在第二个块的 <ol> 以及第三个块的每个 <li> 元素的上面。

html
<h3>A list</h3>
<p>
  Note that the border box doesn't include the number, so neither do the client
  rects.
</p>

<div>
  <strong>Original</strong>
  <ol>
    <li>Item 1</li>
    <li>Item 2</li>
  </ol>
</div>

<div>
  <strong>ol's rect</strong>
  <ol class="withClientRectsOverlay">
    <li>Item 1</li>
    <li>Item 2</li>
  </ol>
</div>

<div>
  <strong>each li's rect</strong>
  <ol>
    <li class="withClientRectsOverlay">Item 1</li>
    <li class="withClientRectsOverlay">Item 2</li>
  </ol>
</div>

示例 3:此 HTML 创建了两个带标题的表格。客户端矩形将绘制在第二个块的 <table> 元素的上面。

html
<h3>A table with a caption</h3>
<p>
  Although the table's border box doesn't include the caption, the client rects
  do include the caption.
</p>

<div>
  <strong>Original</strong>
  <table>
    <caption>
      caption
    </caption>
    <thead>
      <tr>
        <th>thead</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>tbody</td>
      </tr>
    </tbody>
  </table>
</div>

<div>
  <strong>table's rect</strong>
  <table class="withClientRectsOverlay">
    <caption>
      caption
    </caption>
    <thead>
      <tr>
        <th>thead</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>tbody</td>
      </tr>
    </tbody>
  </table>
</div>

CSS

CSS 分别为第一个示例中每个 <div> 块内的段落和 <span> 绘制边框;为第二个示例中的 <ol><li> 绘制边框;为第三个示例中的 <table><th><td> 元素绘制边框。

css
strong {
  text-align: center;
}
div {
  display: inline-block;
  width: 150px;
}
div p,
ol,
table {
  border: 1px solid blue;
}
span,
li,
th,
td {
  border: 1px solid green;
}

JavaScript

JavaScript 代码为所有具有 withClientRectsOverlay CSS 类分配的 HTML 元素绘制客户端矩形。

js
function addClientRectsOverlay(elt) {
  /* Absolutely position a div over each client rect so that its border width
     is the same as the rectangle's width.
     Note: the overlays will be out of place if the user resizes or zooms. */
  const rects = elt.getClientRects();
  for (const rect of rects) {
    const tableRectDiv = document.createElement("div");
    tableRectDiv.style.position = "absolute";
    tableRectDiv.style.border = "1px solid red";
    const scrollTop =
      document.documentElement.scrollTop || document.body.scrollTop;
    const scrollLeft =
      document.documentElement.scrollLeft || document.body.scrollLeft;
    tableRectDiv.style.margin = tableRectDiv.style.padding = "0";
    tableRectDiv.style.top = `${rect.top + scrollTop}px`;
    tableRectDiv.style.left = `${rect.left + scrollLeft}px`;
    // We want rect.width to be the border width, so content width is 2px less.
    tableRectDiv.style.width = `${rect.width - 2}px`;
    tableRectDiv.style.height = `${rect.height - 2}px`;
    document.body.appendChild(tableRectDiv);
  }
}

(() => {
  /* Call function addClientRectsOverlay(elt) for all elements with
     assigned class "withClientRectsOverlay" */
  const elems = document.getElementsByClassName("withClientRectsOverlay");
  for (const elem of elems) {
    addClientRectsOverlay(elem);
  }
})();

结果

规范

规范
CSSOM 视图模块
# dom-element-getclientrects

浏览器兼容性

另见