pil*_*lau 5 html javascript css position dimensions
比方说,我们有未知div容器width和height比身体的全尺寸.
此容器div包含未知数量的div.容器中的所有div都具有不同的大小,除了具有与以下3种类型之一相同的CSS之外:
类型1和2 div具有边距,也可能有填充.类型3 div可以有,也可以两者都没有.
鉴于容器中div的类型是未知的 - 最终目标是在原始内部添加一个辅助容器,其大小足以容纳视口中的所有div(具有溢出:滚动).什么是最便宜的计算方法?
要注意的一些事项:
div 可能会也可能不会(作为一个整体)拥有box-sizing: border-box.这将影响它们的边框,边距和填充的呈现方式,也应该考虑在内.
在类型1和2(浮动div)的情况下,div意味着水平堆叠 - 即,容器应该增长以适合它们的总宽度.这应该被考虑在内.
例如,最右边的div上的右边距应该用于计算,并应该增加容器的宽度.顶部,底部和最左边的div也是如此.
IE8及以下版本不是必需的.
请仅使用vanilla Javascript.没有像jQuery等框架.
谢谢!
一些可视化:

您可能必须自己进行性能测试才能了解哪种方法最快,但无论如何,这是一种非常快速的方法。(jsfiddle)
function getOuterBoxDimensions() {
var original = document.getElementById('original'),
divs = original.getElementsByTagName('div'),
left = 0,
right = original.offsetWidth,
top = 0,
bottom = original.offsetHeight;
for (var i = 0, div; div = divs[i++];) {
if (div.offsetTop < top) {
top = div.offsetTop;
}
if (div.offsetTop + div.offsetHeight > bottom) {
bottom = div.offsetTop + div.offsetHeight;
}
if (div.offsetLeft < left) {
left = div.offsetLeft;
}
if (div.offsetLeft + div.offsetWidth > right) {
right = div.offsetLeft + div.offsetWidth;
}
}
return {
top: top,
left: left,
bottom: bottom,
right: right
};
// Note that dimensions are relative to the original div top left
}
Run Code Online (Sandbox Code Playgroud)
据我所知,offsetLeft、offsetWidth 等无论是否box-sizing: border-box设置都会返回正确的尺寸。如果内部 div 中有 div,那么事情会变得有点复杂 - 您将只想检查原始 div 的子节点。
编辑:这是一个扩展版本,它正确考虑了边距并扩展了新容器以容纳单行中的所有浮动 div(请参阅评论中的讨论)。http://jsfiddle.net/m7N2J/10/
function getOuterBoxDimensions() {
var original = document.getElementById('original'),
divs = original.getElementsByTagName('div'),
left = 0,
right = original.offsetWidth,
top = 0,
bottom = original.offsetHeight,
d = document.defaultView,
style, marginTop, marginBottom, marginLeft, marginRight, float, floatWidth = 0;
for (var i = 0, div; div = divs[i++];) {
if (style = div.currentStyle) {
// May be possible to exclude this if IE7/8 not needed
marginTop = parseFloat(style.marginTop);
marginBottom = parseFloat(style.marginBottom);
marginLeft = parseFloat(style.marginLeft);
marginRight = parseFloat(style.marginRight);
float = style.float;
}
else {
style = d.getComputedStyle(div, null);
marginTop = parseFloat(style.getPropertyValue('margin-top'));
marginBottom = parseFloat(style.getPropertyValue('margin-bottom'));
marginLeft = parseFloat(style.getPropertyValue('margin-left'));
marginRight = parseFloat(style.getPropertyValue('margin-right'));
float = style.getPropertyValue('float');
}
if (float == 'left' || float == 'right') {
floatWidth += div.offsetWidth + marginLeft + marginRight;
if (div.offsetHeight + marginBottom > bottom) {
bottom = div.offsetHeight + marginBottom;
}
}
else {
if (div.offsetTop - marginTop < top) {
top = div.offsetTop - marginTop;
}
if (div.offsetTop + div.offsetHeight + marginBottom > bottom) {
bottom = div.offsetTop + div.offsetHeight + marginBottom;
}
if (div.offsetLeft < left - marginLeft) {
left = div.offsetLeft - marginLeft;
}
if (div.offsetLeft + div.offsetWidth + marginRight > right) {
right = div.offsetLeft + div.offsetWidth + marginRight;
}
}
}
if (right < left + floatWidth) {
right = left + floatWidth;
}
return {
top: top,
left: left,
bottom: bottom,
right: right
};
// Note that dimensions are relative to the original div
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
340 次 |
| 最近记录: |