将 getComputedStyle 与边框框一起使用应该 return 高度无边框和填充
Using getComputedStyle with border-box should return height sans border and padding
EDIT 3/Final:Th Computed Style problem/question 解释如下,但为了其他人的利益,我的真正问题是通过 Flex Boxes 和 Vx 测量与 border-box 一起解决。恕我直言 "display: flex;" 是许多问题的答案,尽管我正在努力让它做我想做的事,但您不必再与 CSS!
作对了
编辑 2:以下内容无疑需要重构,但如果您能告诉我它可以满足我的要求,那就太好了。我必须做的改变是在等式中添加 clientTop 和 offsetTop:-
function resizeContent()
{
var browserHeight = window.outerHeight;
var offesetHeight, offsetWidth;
var viewHeight = window.innerHeight;
var viewWidth = window.innerWidth;
var chromeFootPrint = browserHeight - viewHeight;
var tmpHeight = viewHeight;
if (window.matchMedia("(orientation: portrait)").matches) {
if (viewWidth > viewHeight) {
viewHeight = viewWidth - chromeFootPrint;
viewWidth = tmpHeight + chromeFootPrint;
}
} else {
if (viewWidth < viewHeight) {
viewHeight = viewWidth - chromeFootPrint;
viewWidth = tmpHeight + chromeFootPrint;
}
}
var dimTarget = logScroll;
var offsetTop = dimTarget.offsetTop + dimTarget.clientTop;
var offsetLeft = dimTarget.offsetLeft + dimTarget.clientLeft;
while (dimTarget = dimTarget.offsetParent) {
offsetTop += dimTarget.offsetTop + dimTarget.clientTop;
offsetLeft += dimTarget.offsetLeft + dimTarget.clientLeft;
}
logScrollHeight = viewHeight - (offsetTop + fireBreak);
logScroll.style.height = logScrollHeight + "px";
logScroll.style.width = getStyle(contentDiv).width;
logWindow.style.height = logScroll.style.height;
logWindow.style.width = logScroll.style.width;
logWindow.scrollTop = logWindow.scrollHeight - logScrollHeight;
contentDiv.style.visibility = "visible"; // Now we're presentable
}
这是防火计算:-
var outerStyle = getStyle(wholeScreen);
fireBreak = Number(outerStyle.paddingBottom.match("[0-9.]*"))
+ Number(outerStyle.borderBottomWidth.match("[0-9.]*"))
;
resizeContent();
编辑 1:好的,让我重新表述一下问题:- 如何找出我的 DIV 内容的高度:-
width: 250px;
border: 3px solid green;
padding: 0.5em;
box-sizing: border-box;
我目前必须这样做:-
logScrollHeight = viewHeight -
(offsetTop + Number(getStyle(headerDiv).paddingBottom.match("[0-9.]*")));
原题:-
这肯定是重复的,但经过将近一个小时的查找,我发现了很多 similar/identical 个问题,但没有真正的答案:-(
为什么不从高度中扣除boundryWith和padding?
谢天谢地,boundryBottomWidth 和 PaddingBottom return 已经转换为像素(遗憾的是包括 "px" 字符串)但是标准没有说可用的高度应该是 returned ?
当您将 box-sizing 设置为 border-box 时:
width和height属性包括content、padding和border,但不包括margin
所以当你使用getComputedStyle获取元素的高度时,当然包含了padding和border的高度。
你可以看看box-sizing property and css box model
要获取元素的高度,请不要使用 getComputedStyle
。
getComputedStyle
应该只用于获取当前从不同样式-sheet 应用的解析值。换句话说,你可以把它看作是一种直播风格-sheet,只针对单个元素,具有标准化的单位。
但决不能用它来获取元素的当前高度或宽度。太多因素可能会干扰设置值,一个元素甚至可以在没有任何 CSS height
规则集的情况下具有高度。
所以是的...当height
CSS 规则设置为auto
时,您将得到计算值,这可能与元素的实际高度重合,但也未必如此。
所以为了得到一个元素的显示高度,没有边框和填充,我们需要自己做一些计算。
Element#getBoundingClientRect()
将为我们提供元素的实际显示尺寸,包括转换。 .offsetHeight
将为我们提供包含边框框的未转换高度,.clientHeight
将为我们提供包含填充框的未转换高度。
这意味着我们首先必须获取所有边框和填充计算值,然后获取元素的当前比例,最后从我们使用 [=21= 获取的值中移除缩放的填充+边框框].
这是一个示例,它将在元素的边界框顶部绘制一个新矩形 div,没有填充和边框框。
let marker;
scale.onclick = e => {
element.classList.toggle('scaled');
drawRect();
}
boxSizing.onclick = e => {
element.classList.toggle('boxSized');
drawRect();
}
function drawRect() {
// remove previous marker if any
if (marker && marker.parentNode) {
marker.remove();
marker = null;
}
// first get the border and padding values
let computed = getComputedStyle(element);
let borderLeft = parseFloat(computed.borderLeftWidth);
let borderWidth = borderLeft + parseFloat(computed.borderRightWidth);
let borderTop = parseFloat(computed.borderTopWidth);
let borderHeight = borderTop + parseFloat(computed.borderBottomWidth);
let paddingLeft = parseFloat(computed.paddingLeft);
let paddingWidth = paddingLeft + parseFloat(computed.paddingRight)
let paddingTop = parseFloat(computed.paddingTop);
let paddingHeight = paddingTop + parseFloat(computed.paddingBottom);
// get the current bounding rect, including the border-box
let rect = element.getBoundingClientRect();
// we need to get the current scale since the computed values don't know about it...
let scale = 1 / (element.offsetHeight / rect.height);
// the real displayed height and width without border nor padding
let height = rect.height - ((borderHeight + paddingHeight) * scale);
let width = rect.width - ((borderWidth + paddingWidth) * scale);
// create our rectangle
marker = document.createElement('div');
marker.classList.add('marker');
marker.style.height = height + 'px';
marker.style.width = width + 'px';
// we need to scale border + padding again
marker.style.top = (rect.top + (borderTop + paddingTop) * scale) + 'px';
marker.style.left = (rect.left + (borderLeft + paddingLeft) * scale) + 'px';
document.body.append(marker);
}
#element {
width: 250px;
border: 0.5em solid green;
padding: 0.5em;
margin-top: 12px;
}
#element.scaled {
transform: scale(2);
transform-origin: top left;
}
#element.boxSized {
box-sizing: border-box;
}
.marker {
position: fixed;
width: 3px;
background: rgba(0, 0, 0, .3)
}
<label>scale
<input id="scale" type="checkbox">
</label>
<label>box-sizing
<input id="boxSizing" type="checkbox">
</label>
<div id="element">
Hello
<br> world
</div>
EDIT 3/Final:Th Computed Style problem/question 解释如下,但为了其他人的利益,我的真正问题是通过 Flex Boxes 和 Vx 测量与 border-box 一起解决。恕我直言 "display: flex;" 是许多问题的答案,尽管我正在努力让它做我想做的事,但您不必再与 CSS!
作对了编辑 2:以下内容无疑需要重构,但如果您能告诉我它可以满足我的要求,那就太好了。我必须做的改变是在等式中添加 clientTop 和 offsetTop:-
function resizeContent()
{
var browserHeight = window.outerHeight;
var offesetHeight, offsetWidth;
var viewHeight = window.innerHeight;
var viewWidth = window.innerWidth;
var chromeFootPrint = browserHeight - viewHeight;
var tmpHeight = viewHeight;
if (window.matchMedia("(orientation: portrait)").matches) {
if (viewWidth > viewHeight) {
viewHeight = viewWidth - chromeFootPrint;
viewWidth = tmpHeight + chromeFootPrint;
}
} else {
if (viewWidth < viewHeight) {
viewHeight = viewWidth - chromeFootPrint;
viewWidth = tmpHeight + chromeFootPrint;
}
}
var dimTarget = logScroll;
var offsetTop = dimTarget.offsetTop + dimTarget.clientTop;
var offsetLeft = dimTarget.offsetLeft + dimTarget.clientLeft;
while (dimTarget = dimTarget.offsetParent) {
offsetTop += dimTarget.offsetTop + dimTarget.clientTop;
offsetLeft += dimTarget.offsetLeft + dimTarget.clientLeft;
}
logScrollHeight = viewHeight - (offsetTop + fireBreak);
logScroll.style.height = logScrollHeight + "px";
logScroll.style.width = getStyle(contentDiv).width;
logWindow.style.height = logScroll.style.height;
logWindow.style.width = logScroll.style.width;
logWindow.scrollTop = logWindow.scrollHeight - logScrollHeight;
contentDiv.style.visibility = "visible"; // Now we're presentable
}
这是防火计算:-
var outerStyle = getStyle(wholeScreen);
fireBreak = Number(outerStyle.paddingBottom.match("[0-9.]*"))
+ Number(outerStyle.borderBottomWidth.match("[0-9.]*"))
;
resizeContent();
编辑 1:好的,让我重新表述一下问题:- 如何找出我的 DIV 内容的高度:-
width: 250px;
border: 3px solid green;
padding: 0.5em;
box-sizing: border-box;
我目前必须这样做:-
logScrollHeight = viewHeight -
(offsetTop + Number(getStyle(headerDiv).paddingBottom.match("[0-9.]*")));
原题:-
这肯定是重复的,但经过将近一个小时的查找,我发现了很多 similar/identical 个问题,但没有真正的答案:-(
为什么不从高度中扣除boundryWith和padding?
谢天谢地,boundryBottomWidth 和 PaddingBottom return 已经转换为像素(遗憾的是包括 "px" 字符串)但是标准没有说可用的高度应该是 returned ?
当您将 box-sizing 设置为 border-box 时:
width和height属性包括content、padding和border,但不包括margin
所以当你使用getComputedStyle获取元素的高度时,当然包含了padding和border的高度。
你可以看看box-sizing property and css box model
要获取元素的高度,请不要使用 getComputedStyle
。
getComputedStyle
应该只用于获取当前从不同样式-sheet 应用的解析值。换句话说,你可以把它看作是一种直播风格-sheet,只针对单个元素,具有标准化的单位。
但决不能用它来获取元素的当前高度或宽度。太多因素可能会干扰设置值,一个元素甚至可以在没有任何 CSS height
规则集的情况下具有高度。
所以是的...当height
CSS 规则设置为auto
时,您将得到计算值,这可能与元素的实际高度重合,但也未必如此。
所以为了得到一个元素的显示高度,没有边框和填充,我们需要自己做一些计算。
Element#getBoundingClientRect()
将为我们提供元素的实际显示尺寸,包括转换。 .offsetHeight
将为我们提供包含边框框的未转换高度,.clientHeight
将为我们提供包含填充框的未转换高度。
这意味着我们首先必须获取所有边框和填充计算值,然后获取元素的当前比例,最后从我们使用 [=21= 获取的值中移除缩放的填充+边框框].
这是一个示例,它将在元素的边界框顶部绘制一个新矩形 div,没有填充和边框框。
let marker;
scale.onclick = e => {
element.classList.toggle('scaled');
drawRect();
}
boxSizing.onclick = e => {
element.classList.toggle('boxSized');
drawRect();
}
function drawRect() {
// remove previous marker if any
if (marker && marker.parentNode) {
marker.remove();
marker = null;
}
// first get the border and padding values
let computed = getComputedStyle(element);
let borderLeft = parseFloat(computed.borderLeftWidth);
let borderWidth = borderLeft + parseFloat(computed.borderRightWidth);
let borderTop = parseFloat(computed.borderTopWidth);
let borderHeight = borderTop + parseFloat(computed.borderBottomWidth);
let paddingLeft = parseFloat(computed.paddingLeft);
let paddingWidth = paddingLeft + parseFloat(computed.paddingRight)
let paddingTop = parseFloat(computed.paddingTop);
let paddingHeight = paddingTop + parseFloat(computed.paddingBottom);
// get the current bounding rect, including the border-box
let rect = element.getBoundingClientRect();
// we need to get the current scale since the computed values don't know about it...
let scale = 1 / (element.offsetHeight / rect.height);
// the real displayed height and width without border nor padding
let height = rect.height - ((borderHeight + paddingHeight) * scale);
let width = rect.width - ((borderWidth + paddingWidth) * scale);
// create our rectangle
marker = document.createElement('div');
marker.classList.add('marker');
marker.style.height = height + 'px';
marker.style.width = width + 'px';
// we need to scale border + padding again
marker.style.top = (rect.top + (borderTop + paddingTop) * scale) + 'px';
marker.style.left = (rect.left + (borderLeft + paddingLeft) * scale) + 'px';
document.body.append(marker);
}
#element {
width: 250px;
border: 0.5em solid green;
padding: 0.5em;
margin-top: 12px;
}
#element.scaled {
transform: scale(2);
transform-origin: top left;
}
#element.boxSized {
box-sizing: border-box;
}
.marker {
position: fixed;
width: 3px;
background: rgba(0, 0, 0, .3)
}
<label>scale
<input id="scale" type="checkbox">
</label>
<label>box-sizing
<input id="boxSizing" type="checkbox">
</label>
<div id="element">
Hello
<br> world
</div>