使用“缩放”属性转换元素后,我无法获取元素的坐标。我需要知道所有 4 个角的坐标。我通常会使用 getBoundingClientRect 属性来完成此操作,但是,当元素缩放时,该属性似乎无法正常工作。我附上了一个简短的 jsfiddle 链接来显示什么似乎不起作用。我使用的是 Chrome,但 Firefox 上也存在该行为。
http://jsfiddle.net/GCam11489/0hu7kvqt/
HTML:
<div id="box" style="zoom:100%">Hello</div><div></div><div></div>
JS:
var div = document.getElementsByTagName("div");
div[1].innerHTML = "PreZoom Width: " + div[0].getBoundingClientRect().width;
div[0].style.zoom = "150%";
div[2].innerHTML = "PostZoom Width: " + div[0].getBoundingClientRect().width;
当我运行该代码时,缩放前后的宽度都显示为“100”。
我找到了很多信息,但我发现的所有内容似乎都表明这是 Chrome 上的一个已知错误,并且已被修复。有谁知道如何纠正这个问题或者我可能做错了什么?
关于错误报告的评论涉及一些详细的规则。问题,但其状态似乎是“WontFix”,所以您可能不走运。
transform: scale(1.5)
而不是缩放,您会在 getBoundingClientRect()
中获得正确的值,但这会扰乱页面布局。window.getComputedStyle(div[0]).zoom
获取元素的缩放值(以小数为单位)并将其乘以 getBoundingClientRect()
工具提示组件出现问题。
创建此函数来获取应用于元素的所有缩放。然后我也使用该缩放将其应用到全局工具提示。完成后即可正确对齐。
请注意,它会检查父级parent
el.parentElement?.parentElement
,这样就不会考虑全局浏览器缩放。
export const getZoomLevel = (el: HTMLElement) : number[] => {
const zooms = []
const getZoom = (el: HTMLElement) => {
const zoom = window.getComputedStyle(el).getPropertyValue('zoom')
const rzoom = zoom ? parseFloat(zoom) : 1
if (rzoom !== 1) zooms.push(rzoom)
if (el.parentElement?.parentElement) getZoom(el.parentElement)
}
getZoom(el)
zooms.reverse()
return zooms
}
如果您不想缩放“工具提示”组件,则将获得调整缩放的矩形,如下所示:
export const getRect = (el: HTMLElement) : Partial<DOMRect> => {
if (!el) return { x: 0, y: 0, width: 0, height: 0, top: 0, right: 0, bottom: 0, left: 0 }
let rect = el?.getBoundingClientRect();
const zooms = getZoomLevel(el)
const rectWithZoom = {
bottom: zooms.reduce((a, b) => a * b, rect.bottom),
height: zooms.reduce((a, b) => a * b, rect.height),
left: zooms.reduce((a, b) => a * b, rect.left),
right: zooms.reduce((a, b) => a * b, rect.right),
top: zooms.reduce((a, b) => a * b, rect.top),
width: zooms.reduce((a, b) => a * b, rect.width),
x: zooms.reduce((a, b) => a * b, rect.x),
y: zooms.reduce((a, b) => a * b, rect.y),
}
return rectWithZoom
}
这是一篇相当老的帖子,但我遇到了同样的问题,我在一个小面板上有一个有角度的材质项目,它的像素比低于 1,这使得所有东西都非常小。为了解决这个问题,我在身体上添加了变焦来解决这个问题。
角度材料 (7) 滑块使用
getBoundingClientRect()
来确定其位置,这使得滑块比我希望的走得更远。
我使用了上面提到的 eruditespirit 这样的解决方案。
if (Element.prototype.getBoundingClientRect) {
const DefaultGetBoundingClientRect = Element.prototype.getBoundingClientRect;
Element.prototype.getBoundingClientRect = function () {
let zoom = +window.getComputedStyle(document.body).zoom;
let data = DefaultGetBoundingClientRect.apply(this, arguments);
if (zoom !== 1) {
data.x = data.x * zoom;
data.y = data.y * zoom;
data.top = data.top * zoom;
data.left = data.left * zoom;
data.right = data.right * zoom;
data.bottom = data.bottom * zoom;
data.width = data.width * zoom;
data.height = data.height * zoom;
}
return data;
};
}
我在寻找解决方案时遇到了这个问题。 我有一个
position:absolute
元素,当调整窗口大小时我会更新其位置,iOS 在放大/缩小时触发此元素。
我发现
window.visualViewport
其中包含抵消这一点所需的关键信息,包括缩放信息。
我的使用缩放偏移设置元素位置/大小的解决方案:
positionNavHighlight(link: HTMLElement) {
const rect = link.getBoundingClientRect();
const offsetTop = window.visualViewport.offsetTop;
const offsetLeft = window.visualViewport.offsetLeft;
navActiveBg.style.top = `${rect.top + offsetTop}px`;
navActiveBg.style.left = `${rect.left + offsetLeft}px`;
navActiveBg.style.height = `${rect.height}px`;
navActiveBg.style.width = `${rect.width}px`;
}
没有解决方案,但(至少在 Chromium 中)BoundingClientRectangle 不补偿 CSS 缩放的原因似乎是不同的缩放系数应导致不同的 BoundingRectangle:
https://issues.chromium.org/issues/41461010#comment29
虽然我认为提到的提交只讨论了直接获得CSS缩放属性的元素(而不是它们的子元素)的BoundingRectangle - 否则@G-Cam不会在2017年遇到这个问题 - 这很可能就是原因为什么继承 CSS 缩放的元素也是如此。