javascript getBBox() 与 getBoundingClientRect() 与 getClientRects()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33688549/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 16:48:26  来源:igfitidea点击:

getBBox() vs getBoundingClientRect() vs getClientRects()

javascriptdomsvg

提问by Troopers

I am unable to find an explicit reference for the use of these functions: getBBox()vs getBoundingClientRect()vs getClientRects().

我无法找到使用这些函数的明确参考: getBBox()vs getBoundingClientRect()vs getClientRects().

Could you explain what they do and what are the coordinates (and their referential) they return?

你能解释一下他们做什么以及他们返回的坐标(和他们的参考)是什么?

回答by Robert Longson

getBBoxis defined in the SVG specificationit returns coordinates in the localcoordinate system after the application of transforms.

getBBoxSVG 规范中定义,它在应用变换后返回本地坐标系中的坐标。

getBoundingClientRectand getClientRectsare defined in the CSSOM specification. Their main difference is that they return coordinates in the outerSVG coordinate system.

getBoundingClientRectgetClientRectsCSSOM 规范中定义。它们的主要区别在于它们返回外部SVG 坐标系中的坐标。

回答by wangkaibule

someelements(like spantag) will have multiple ClientRectswhen they are wrapped into multiple lines.MDN Element.getClientRects()
and a BoundingRectis the unionof ClientRectsof a element.MDN Element.getBoundingClientRect()

一些元素(如span标签)在被包装成多行时会有多个ClientRectsMDN Element.getClientRects()
BoundingRect是元素的ClientRects联合MDN Element.getBoundingClientRect()

回答by foxiris

This is an example I copied from MDN Element.getClientRects()and I added addBoundingClientRectOverlayfunction to compare addClientRectsOverlay. You can see the red rectangle is from getClientRectsand the black dash rectangle is from getBoundingClientRect, so you can tell what's different. enter image description here

这是我从 MDN Element.getClientRects()复制的一个例子,我添加了addBoundingClientRectOverlay函数来比较addClientRectsOverlay。您可以看到红色矩形来自getClientRects,黑色虚线矩形来自getBoundingClientRect,因此您可以分辨出不同之处。 在此处输入图片说明

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.
  var rects = elt.getClientRects();

  for (var i = 0; i != rects.length; i++) {
    var rect = rects[i];
    var tableRectDiv = document.createElement("div");
    tableRectDiv.style.position = "absolute";
    tableRectDiv.style.border = "1px solid red";
    var scrollTop =
      document.documentElement.scrollTop || document.body.scrollTop;
    var 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);
  }
}
function addBoundingClientRectOverlay(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.
  var rect = elt.getBoundingClientRect();

  var tableRectDiv = document.createElement("div");
  tableRectDiv.style.position = "absolute";
  tableRectDiv.style.border = "1px dashed #321";
  var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
  var scrollLeft =
    document.documentElement.scrollLeft || document.body.scrollLeft;
  tableRectDiv.style.margin = tableRectDiv.style.padding = "0";
  tableRectDiv.style.top = rect.top + scrollTop+1 + "px";
  tableRectDiv.style.left = rect.left + scrollLeft+1 + "px"; // we want rect.width to be the border width, so content width is 2px less.
  tableRectDiv.style.width = rect.width - 4 + "px";
  tableRectDiv.style.height = rect.height - 4 + "px";
  document.body.appendChild(tableRectDiv);
}
(function() {
  /* call function addClientRectsOverlay(elt) for all elements with assigned css class "withClientRectsOverlay"? */
  var elt = document.getElementsByClassName("withClientRectsOverlay");
  for (var i = 0; i < elt.length; i++) {
    addClientRectsOverlay(elt[i]);
    addBoundingClientRectOverlay(elt[i]);
  }
})();
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;
}
<!-- Learn about this code on MDN: https://developer.mozilla.org/en-US/docs/Web/API/Element/getClientRects -->

<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><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><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>