在没有 getBoundingClientRect 的情况下获取相对于文档的元素偏移量(Webkit 错误)
Posted
技术标签:
【中文标题】在没有 getBoundingClientRect 的情况下获取相对于文档的元素偏移量(Webkit 错误)【英文标题】:Get element offset relative to document without getBoundingClientRect (Webkit bug) 【发布时间】:2017-03-19 13:11:39 【问题描述】:定位工具提示/弹出窗口通常只是使用 getBoundingClientRect() 或 jQuery 的 offset() 函数(内部使用 getBoundingClientRect)来获取相对于文档或窗口,但是如果您放大某些 Webkit 浏览器,这些函数开始返回意外/错误的结果,因为 getBoundingClientRect 函数在 Webkit 中的实现很奇怪。这一直是个问题,并且由于某种原因从未得到解决。
问题:我如何(如果可能的话)计算元素相对于文档的精确像素偏移量不使用 getBoundingClientRect() 以便值 不 > 改变缩放?
【问题讨论】:
你能在这里澄清一些事情吗?您说“某些 webkit 浏览器”是否有特定的问题,例如它发生在 Chrome 中还是仅在 Opera 中?缩放是指移动设备上的捏缩放、桌面上的浏览器缩放(^+/^- 或⌘+/⌘-),还是 CSS 缩放?例如,我在 Chrome (Canary) 中通过制作一个可点击的 div 进行测试,并让它记录其 getBoundingClientRect 并在更改浏览器缩放级别后检查值,除了一两个子像素定位怪癖之外,我没有看到值发生变化。 我不确定确切的版本。我所知道的是它发生在我的手机上。使用最新的移动 Chrome。我确实在谈论捏缩放。对困惑感到抱歉。因此,当您放大(捏)时,例如 jQuery 的 offset().left 会发生变化。并且越靠近您“捏”的屏幕左边缘,offset().left 值就越大。 你能把一个简化的例子放在一起吗?我在本地没有看到这种情况发生,因此,如果您能够使用重现(或制作 JSFiddle/JSBin)所需的最低 html/CSS/JS 更新您的答案,这将对某人有很大帮助能够帮助您弄清楚发生了什么:) 当然。 output.jsbin.com/setogicota 在 android 上的 Chrome 上打开,然后捏缩放。工具提示应该贴在输入的右下角,但事实并非如此。在 Chrome 上(我在 Linux 上),如果我放大它会按预期工作。如果我现在从左侧位置减去 scrollX,从顶部位置减去 scrollY,它就可以工作。但后来它在桌面 Chrome 上被搞砸了。看来改成 getBoundingClientRect 会逆转效果。 【参考方案1】:我在https://jsbin.com/vaculorita/1/edit?css,js,output 中解决了这个问题
我不确定 jQuery 的偏移量试图做什么,但切换到绝对定位和手动使用 getBoundingClientRect 的组合对我有用。
HTML
<div id="tooltip">Tooltip</div>
<input type="text" id="username">
CSS
#username
margin-left: 54px;
margin-top: 21px;
#tooltip
position: absolute;
left: 0;
top:0;
JS
$(function()
function moveTooltip()
var $tooltip = $('#tooltip').first();
var $input = $('#username').first();
var rect = $input.get(0).getBoundingClientRect();
$tooltip.css('left', rect.left + $input.width());
$tooltip.css('top', rect.top + $input.height());
moveTooltip();
$(window).on('resize scroll', moveTooltip);
);
【讨论】:
这不能正常工作。如果页面宽度大于窗口宽度,您会得到相同的结果。检查此垃圾箱:jsbin.com/pozujezufi/1/edit?html,css,js,output。在输出中向右滚动,您会再次看到偏移量错误。我唯一改变的是我将主体设置为 3000 像素的宽度和高度。 当然,这是一个公平的观点,如果您删除事件处理程序并仅定位元素并且不用担心在浏览器滚动/调整大小/缩放时尝试移动它,它应该可以工作(我认为最初您可能会遇到问题,因为您的工具提示是position: fixed
而不是 absolute
。有关工作示例,请参阅 jsbin.com/lalumi/2/edit?js。
问题是我的整个目标是将元素动态移动到其他元素。所以我想在点击/焦点/任何东西上定位一个元素右侧的弹出窗口。它必须是动态的和动态的。
您仍然可以这样做,您需要从事件处理程序中获取要移动到的元素,然后您可以将另一个元素移动到该元素的相应位置。有几种不同的方法可以实现类似的东西,但这可能超出了这个问题/答案的范围。
嗯,我不认为我们在同一条路上。我面临的整个问题是,如果我在我的应用程序上进行捏缩放并专注于输入,我的工具提示会转到错误的位置,因为我无法获得准确的偏移位置。该问题的目标是修复此垃圾箱:jsbin.com/pozujezufi/1/edit?html,css,js,output。目前这个垃圾箱在桌面上不能正常工作,而在我的手机上它可以工作。以上是关于在没有 getBoundingClientRect 的情况下获取相对于文档的元素偏移量(Webkit 错误)的主要内容,如果未能解决你的问题,请参考以下文章
更改 getBoundingClientRect() 的事件或观察者
Windows / IE11 中的范围元素上的 getBoundingClientRect 不正确
js中getBoundingClientRect()方法详解