SVG:获取元素相对于页面的位置

Posted

技术标签:

【中文标题】SVG:获取元素相对于页面的位置【英文标题】:SVG: Getting the position of an element relative to the page 【发布时间】:2012-03-26 11:42:13 【问题描述】:

我想在用户单击 SVG 图表中的元素时显示叠加层(html div)。为了可视化我遇到的问题,假设 SVG 图像具有 6 个元素的水平行。在单击事件中,我获取元素的坐标并使用它们在其旁边显示叠加层。问题是当我从左到右单击元素时,我注意到元素和叠加层之间的水平偏移越来越小。也就是说,第 6 个元素显示的叠加层比第一个元素更接近它。这在 Chrome 和 FF 中都会发生,这是一个问题,因为有时覆盖层会覆盖元素本身。

起初我使用的是 JQuery 的 position() 属性,它没有表现出我上面描述的行为,但它在 Chrome 和 Firefox 中返回的值非常不同,而且 JQuery 在 svg 元素上没有正式支持它。所以我尝试了 DOM 的标准 offsetLeft 和 offsetTop,以及 svg 的 x.animVal.value 属性和我在网上找到的各种库,但它们都有相同的不稳定偏移问题。我认为发生这种情况是因为 svg 图像被缩放,所以我正在寻找一种方法来获取相对于包含它的实际 html 文档的 svg 元素位置。有没有办法做到这一点?

【问题讨论】:

【参考方案1】:

如果您自 3 月以来没有解决任何问题(以及其他遇到此问题的人),请在您的 SVG 节点上尝试 getBoundingClientRect()

返回一个ClientRect 对象,该对象为您提供相对于文档的顶部、底部、左侧、右侧、宽度和高度。能够使用它来将 Twitter Bootstrap 弹出框(div)定位在 SVG 矩形旁边。

【讨论】:

请注意,这不考虑滚动位置。 正确 - 不滚动。有解决办法吗? 使用document.body.scrollTop/document.body.scrollLeft获取页面的滚动偏移量。【参考方案2】:

jQuery 的 position() 不适用于 SVG 元素。有a ticket。

您可以使用原生 SVG 方法 getBBox() 来获取 SVG 元素的位置。

示例

$('svg circle')[0].getBBox();

【讨论】:

getBBox() 告诉您该元素的边界框的大小,但仅当 SVG 为 100% 比例时才准确。【参考方案3】:

你可以通过这个小函数获取任何元素相对于页面的位置坐标,也可以是

function getOffset(element)

    var bound = element.getBoundingClientRect();
    var html = document.documentElement;

    return 
        top: bound.top + window.pageYOffset - html.clientTop,
        left: bound.left + window.pageXOffset - html.clientLeft
    ;

var offset = getOffset(svg);var x = offset.left;var y = offset.top;强>

现场演示:https://codepen.io/martinwantke/pen/rpNLWr

【讨论】:

太棒了!非常感谢 - 我今天花了太多时间在 svg 中的数据元素上显示工具提示。根据鼠标位置,我让它半工作,但需求发生了变化,你的解决方案真的很方便。 感谢分享,但是如果您想要一个 SVG 元素相对于 SVG 文档的偏移量怎么办?

以上是关于SVG:获取元素相对于页面的位置的主要内容,如果未能解决你的问题,请参考以下文章

具有位置的元素:相对于 SVG 剪辑路径未在 Safari 中显示

SVG中如何获取元素的坐标?

jQuery获取元素相对于窗口的位置

获取元素在页面中位置

如何获取 svg 元素的坐标?

获取元素相对于父容器的位置/偏移量?