查找绝对定位元素的参考系

Posted

技术标签:

【中文标题】查找绝对定位元素的参考系【英文标题】:Find absolutely positioned element's frame of reference 【发布时间】:2016-08-01 10:18:12 【问题描述】:

我正在使用 javascript 创建一个绝对定位元素。该元素将在各种不同的上下文中使用。所以与它相关的元素可以是它的父元素,也可以是任何其他元素,包括body

在将元素放入 DOM 之前,我需要设置元素的位置(例如 lefttop)。有没有办法找出我的新元素将相对于哪个元素定位?我知道哪个元素将是它的直接父元素。但最接近的元素具有 position 样式而不是 static(我的新元素将被定位的元素)可能是不同的元素。

我考虑过遍历 DOM 树并检查每个父元素的 position 样式,但这似乎是一种非常复杂的方法。

那么,有没有更好的方法来找出哪个元素是我的绝对定位元素位置的参考框架

【问题讨论】:

我认为你在正确的轨道上。也许为此目的定义一个遍历函数并且每次都使用这个函数? 为什么看起来很复杂?这正是浏览器确定定位的方式。只需编写一个递归函数来检查元素的父级,直到找到没有 position:static 的父级。 【参考方案1】:

听起来你想要.offsetParent(),它将获取元素的第一个定位父级(我假设以最有效的方式)。根据绝对定位的定义,

绝对

不要为元素留出空间。相反,将其放置在 相对于其最近定位的祖先的指定位置(如果有), 或以其他方式相对于包含块。绝对定位 框可以有边距,并且它们不会与任何其他框一起折叠 边距。

它完全符合您的要求。

编辑:对于纯 JavaScript 解决方案,迭代每个父级是唯一的方法。试试:

function offsetParent(elem) 
    var parent = elem.parentNode;

    if (window.getComputedStyle(parent).position !== 'static' || parent.tagName === 'BODY') 
        return parent;
     else 
        return offsetParent(parent);
    

【讨论】:

引用是关于 position: absolute; CSS 属性的,解释了为什么 offsetParent() 符合您的描述。我喜欢给出解释性的答案。 但为什么这是公认的答案?正如@n_user 在他的回答中定义的那样,offsetParent() 在您的情况下不起作用,因为它会抓取所有元素,而不仅仅是定位的absolutely,这不是上述问题中的任务。你能解释一下吗,可能是 @KWeiss 这个答案获取了元素将相对定位的父元素,它可以是具有除静态之外的任何位置的任何元素,@Farside。该问题未指定它必须是绝对父级。 @Makaze,你说什么?它清楚地说明了这一点,在描述中以粗体显示,并在问题主体中:Find absolutely located element's frame of reference 我不是在寻找 position:absolute 元素,而是在寻找它所在的元素。我已经编辑了这个问题,因为有两个人误解了它。【参考方案2】:

有一些方法,但它们需要遍历所有 DOM 元素,这可能不会很快。

以下是 jQuery 中可能为您选择的元素:

$('*').filter(function()
   var position = $(this).css('position');
   return position === 'absolute';
);

如果你有目标选择器,并且需要确定它是否嵌套到任何父元素,使用绝对定位,你可以使用 parent() 遍历所有父元素:

// it will return all the parent selectors, with the absolute positioning
$(targetSelector).parents().filter(function() 
    var position = $(this).css('position');
    return position === 'absolute';
); 

另请参阅.offsetParent(),这在某种程度上可能有用,但不适合您的目的,因为您的任务有点不同。原因如下:

.offsetParent() 方法允许我们在 DOM 树中搜索这些元素的祖先,并构造一个新的 jQuery 对象,包裹在最近的定位祖先周围。如果一个元素的 CSS 位置属性为relativeabsolutefixed,则称该元素已定位。

这意味着,它将抓取第一个父元素,该元素定义了 任何 的 CSS 位置属性:relativeabsolutefixed。只要您需要过滤掉“位置:绝对;”它没有按您期望的方式工作,您需要采用我在上面几段提出的解决方案。

【讨论】:

以上是关于查找绝对定位元素的参考系的主要内容,如果未能解决你的问题,请参考以下文章

讲讲相对定位、绝对定位、固定定位的理解?

ElementFromPoint 用于绝对定位的元素?

HTML定位——绝对定位和相对定位固定定位

CSS绝对定位与相对定位的区别?

CSS样式当时 CSS定位 绝对定位

html绝对定位的元素如何让它始终居中?