相对于父级滚动div而非窗口找到偏移量

29

我有一个放置在窗口内部的滚动元素。

假设有一个带有类名为“currentContainer”的division,overflow属性设置为auto,并且该division包含大量文本,因此它肯定足够大以进行滚动。

现在,我必须根据“currentContainer”向下滚动了多少以及特定元素相对于其父滚动div(即“currentCoantainer”)的偏移量来进行一些计算。

但是,在计算偏移量时,我总是得到与窗口相关的内部子元素的偏移量,而不是与“currentContainer”相关的偏移量。

JS FIDDLE

@Shikkediel 我还尝试使用position().top代替offset().top,但结果仍然相同。请查看:

JS FIDDLE 2

请不要建议使用:

$("<reference of scrolling element").scrollTop() 
+ 
$("<reference of child element whose offset I want to calculate>").offset().top
因为这会使我接下来要做的实际计算变得更加复杂。
我不想使用上述方法的原因是,我正在尝试修改一个现有代码,该代码已经非常混乱,但在窗口方面完美地工作,我只需要更新它,使其开始相对于其父级滚动div工作。
我尝试使用上述方法,但它给我带来了一堆麻烦,因为这些函数紧密耦合。所以我认为,如果我能获得简单而直接的解决方案,即用其他东西替换.offset().top,那就好了。
我尝试调试代码,但仍然没有运气,我已将实际代码添加到http://jsfiddle.net/arpitajain/kwkm7com/
P.S. 这是实际代码,但不完整。我认为其余的代码对于此错误并不重要。

不是很清楚你在问什么,但是可以看一下.position(),这是相对于父元素的偏移量。 - Shikkediel
好的,我会重新表达我的句子。 - Arpita
干杯。一个好的描述可以增加找到解决方案的机会。 :-) - Shikkediel
抱歉我的英语不太好,但我已经尽力详细解释了事情,如果有什么我无法解释清楚的地方,请告诉我。 - Arpita
你的问题仍然不够清晰。你能否举例说明使用'px'单位和一些mspaint图像提示? - Harsh Baid
我已经删除了答案,因为它实际上并没有提供解决方案。而且似乎通过妥协找到了一种解决方法。 - Shikkediel
4个回答

23

您可以从子元素的偏移量中减去父元素的偏移量。这样做会让您需要做的其他事情变得复杂吗?

$(".getoffset").offset().top - $(".getoffset").offsetParent().offset().top

http://jsfiddle.net/kmLr07oh/2/


非常好的回答,谢谢! - Mohan
什么是非jQuery方式? jQuery现在已经过时了。 - Mario Eis
一些需要注意的事项:
  1. 确保你的Parent_Div不会动态改变。 -- 所以最好使用一个**固定的元素引用**来表示Parent_Div,而不是使用像Child_Element_ToGetOffsetRelToParentDiv.parent这样的方式。
  2. 如果你在一个可滚动的Parent_Div内部,也许你想要添加**+ Parent_Div.scrollTop;**。 所以例如:const offset = Child_Element_ToGetOffsetRelToParentDiv.getBoundingClientRect().top - Parent_Div.getBoundingClientRect().top + Parent_Div.scrollTop;
- Nor.Z

12

这可能就是您正在寻找的内容。

var scrollOffset = $('.container .element')[0].offsetTop - $('.container')[0].offsetTop;

并且使用原生JavaScript

var scrollOffset = document.querySelector('.container .element').offsetTop - document.querySelector('.container').offsetTop;

———————————

如果您需要背景知识,以下内容将帮助您了解大部分信息:

// Position of first element relative to container top
var scrollTop = $(".container .element").offset().top - $(".container").offset().top;

// Position of selected element relative to container top
var targetTop = $(".container > *").offset().top - $(".container").offset().top;

// The offset of a scrollable container
var scrollOffset = scrollTop - targetTop;

// Scroll untill target element is at the top of its container
$(".container").scrollTop(scrollOffset);

另请参阅:在可滚动的 div 中计算元素的 offset top


你回答的修改部分正好符合我的预期。 - Ray

6
一个纯JavaScript的解决方案是:
const el = document.querySelector('.getoffset');
const offset = el.getBoundingClientRect().top - el.offsetParent.getBoundingClientRect().top;

Fiddle: http://jsfiddle.net/njb1xcz0/


不起作用,结果的数字太大了。滚动 div 前面的整个空间也被添加了,这是不正确的。 - ygoe
在我发布的fiddle中,使用原生JS计算出的值与使用jQuery计算出的值完全相同。请提供一个fiddle,以便我可以重现您的问题。 - andreivictor
1
我认为我的滚动容器可能缺少了另一个评论中提到的position: relative。我找到的关于这个主题的所有答案都没有包括这个重要的点,否则offsetTop(任何解决方案的主要部分)就无法工作。 - ygoe

0

在我的测试中

//has the same value
console.log(
    'compare:',
    $("#element").offset().left - $("#container").offset().left,
    $("#element").position().left
);

这意味着它相对于父元素具有绝对定位。要相对于父元素获取相对位置,我使用:

let relative_position_x = Element.position().left + scroller.scrollLeft();
let relative_position_y = Element.position().top + scroller.scrollTop();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接