我现在正在重写一些旧代码以与现代浏览器一起使用。有一个问题一直困扰着我:视口大小。我希望将 DIV 元素放在中心,但是使用滚动条,它不会正确。另外,我希望在右边框附近放置一个按钮,但滚动条呈现在我的按钮上。
我正在使用简单的...
window.innerWidth
...获取宽度,但不会考虑垂直滚动条(如果有)。我在 MDN 文档中查找了一些内容来给我正确的数字......
document.body.clientWidth (give a smaller number, about twice width of scrollbar)
这个属性对于 body 也有特殊的行为,但对我来说这是错误的。 我没有找到一种方法来获取每个滚动条的大小,所以我现在没有想法了。 我知道这个问题被很多人问到,就像这里,但我希望在新的浏览器和最新的 ECMAScript 定义中深入思考这个主题,并具有一些复古的兼容性。
我制作了一个网页来使用这些属性及其值。在这种情况下,获得所需的东西(正确的绿框定位)的唯一方法似乎是经验主义。这就是代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
#result { width:2000px; height:1600px; }
#bottomright {
position: fixed;
right: 0px;
bottom: 0px;
width: 64px;
height: 64px;
border: black solid 1px;
}
</style>
<script type="text/javascript">
function ini() {
var Sizes = [
{ method:"window.inner", color:"red", width:window.innerWidth, height:window.innerHeight },
{ method:"document.body.offset", color:"blue", width:document.body.offsetWidth, height:document.body.offsetHeight }
];
var html = "<h2>Methods do get de window size:</h2>";
for(let i=0; i<Sizes.length; i++) {
html += '<p style="color:'+Sizes[i].color+';">'+Sizes[i].method+'</p>';
document.body.appendChild(Box(0, 0, 64, 64, Sizes[i].color));
document.body.appendChild(Box(Sizes[i].width-66, 0, 64, 64, Sizes[i].color));
document.body.appendChild(Box(0, Sizes[i].height-66, 64, 64, Sizes[i].color));
document.body.appendChild(Box(Sizes[i].width-66, Sizes[i].height-66, 64, 64, Sizes[i].color));
}
const size = realSize();
document.body.appendChild(Box(size.width-34, size.height-34, 32, 32, "green"));
html += '<p style="color:green;">Real Size</p>';
document.getElementById("result").innerHTML = html;
}
function Box(x, y, w, h, color) {
const elm = document.createElement("div");
elm.style.border = color+" solid 1px";
elm.style.position = "fixed";
elm.style.left = x.toString()+"px";
elm.style.top = y.toString()+"px";
elm.style.width = w.toString()+"px";
elm.style.height = h.toString()+"px";
return elm;
}
function realSize() {
const elm = document.createElement("div");
elm.style.id = "sizeFinder"; // will look at later
elm.style.border = "0px"; // just in case
elm.style.position = "fixed";
elm.style.right = "0px"; // the real right
elm.style.bottom = "0px"; // the real bottom
elm.style.width = "10px"; // some width, just in case
elm.style.height = "10px"; // some height, just in case
document.body.appendChild(elm);
const box = elm.getBoundingClientRect()
return { width:box.x+10, height:box.y+10 };
}
</script>
<title>Window Size Test</title>
</head>
<body onload="ini();">
<h1>Window Size Test</h1>
<div id="result"></div>
<div id="bottomright"></div>
</body>
</html>
这是结果:
请注意,我将绿色框设置为一半大小,以免覆盖其他框。另外,在角落固定一个隐形盒子以便在需要时获取实际窗口大小可能是个好主意,我想这就是我要做的。
请测试并分享评论,我仍然担心这是否适用于任何浏览器并具有一些复古兼容性。
Visual Viewport API 文档提供了“模拟位置:设备固定”的示例和演示。这个例子使用了与OP的答案类似的方法。我实现了一个适合我的版本:
// this viewport object measures the size of the Visual Viewport
const viewport = {
width: 0,
height: 0,
guage: document.createElement('div'),
update: function () {
const boundingRect = this.guage.getBoundingClientRect();
this.width = boundingRect.width;
this.height = boundingRect.height;
},
};
viewport.guage.style.position = 'fixed'; // maintains div position relative to the top-left of the Visual Viewport (ignores flow)
viewport.guage.style.left = '0px'; // maintains div x-position at the Visual Viewport left
viewport.guage.style.right = '0px'; // maintains div width at the Visual Viewport right, minus scrollbar
viewport.guage.style.top = '0px'; // maintains div y-position at the Visual Viewport top
viewport.guage.style.bottom = '0px'; // maintains div height at the Visual Viewport bottom, minus scrollbar
viewport.guage.style.visibility = 'hidden'; // keeps div in DOM tree but does not render
document.body.append(viewport.guage);
// use the resize event on the window.visualViewport object to maintain measurement of the Visual Viewport
window.visualViewport.addEventListener('resize', () => viewport.update());
// -------------------- demonstration --------------------
// the following code is for demonstration only
// this box will maintain a 10 pixel padding from the Visual Viewport's right and bottom edges
const box = document.createElement('div');
box.style.position = 'fixed';
box.style.left = `10px`;
box.style.top = `10px`;
box.style.backgroundColor = 'lightgray';
box.style.outline = 'solid black 1px';
// this box will force scrollbars to appear
const bars = document.createElement('div');
bars.style.width = '3000px';
bars.style.height = '3000px';
bars.style.visibility = 'hidden';
// add boxes to DOM
document.body.append(box);
document.body.append(bars);
// update the viewport and set the width/height of the visible box
window.visualViewport.addEventListener('resize', () => {
viewport.update();
const userOffset = {
x: 10,
y: 10,
};
const boxdata = box.getBoundingClientRect();
const width = viewport.width - boxdata.x - userOffset.x;
const height = viewport.height - boxdata.y - userOffset.y;
box.style.width = `${width}px`;
box.style.height = `${height}px`;
});