30
var offset = $(selector).offset();

如果我们上下滚动页面,偏移变量的值会发生变化,我想要精确和固定的偏移值,同时保持“选择器”默认值(静态)的位置。我该怎么做?

4

6 回答 6

40

您总是可以计算偏移量,并考虑滚动位置:

var offset_t = $(selector).offset().top - $(window).scrollTop();
var offset_l = $(selector).offset().left - $(window).scrollLeft();
于 2012-04-24T12:32:06.590 回答
9

另一个潜在的原因是如果你<body>碰巧有设置的 CSS overflow-x: hidden;- 这完全破坏了 jQuery 的offset()方法。

在这种情况下,$(window).scrollTop()始终为 0,因此接受的答案不起作用。

于 2017-01-27T18:14:41.983 回答
6

遇到同样的问题后,只想在这里添加我的答案:

在得到上述行为后,我查看了 jQuery 文档并发现

jQuery 不支持获取隐藏元素的偏移坐标或考虑在 body 元素上设置的边框、边距或填充。

我试图获得偏移量的元素实际上被设置为display:none;给我一个错误的偏移量,该偏移量在滚动时会发生变化(即使元素没有移动)。

因此,请确保您没有尝试获取隐藏元素的偏移量!希望这可以帮助某人:)

于 2015-12-04T02:47:45.703 回答
6

我有一个与原始问题非常相似的问题。偏移量有点棘手。希望这将有助于解决您的问题,就像我的问题一样。我有 3 个 JSFiddles 来演示。

  1. 如果您基于offset().top窗口中的 div 元素,您将始终获得一个静态数字(即,如果$(window)是滚动的东西并且您在窗口内有一个已offset().top应用的 div,则该 div 将始终具有一个静态数字)。$(window)无论您向下滚动多远,此偏移量都是元素从顶部开始存在的确切像素数。对于我的每个 JSFiddles,我将查看对象$('div#offset')距其滚动容器顶部的距离。在第一个示例中,请注意数字没有变化:

https://jsfiddle.net/BrianIsSecond/ehkgh2gu/

  1. 现在,可以说$(window)不是滚动的容器。您改为创建一个具有“overflow-y:scroll;”的 div 属性集。在这种情况下,这些$('div#offset').offset().top行为与前面的示例非常不同。当您滚动时,您会注意到它会发生变化。对于我的 JSFiddle 示例,我只是将div#overflow具有overflow-y:scroll;属性集的所有内容都包装在其中。参见示例:

https://jsfiddle.net/BrianIsSecond/tcs390h6/ <--- 还要注意 div#overflow 不是 100% 高的。我让它比 100% 少了 100 像素。我用它来说明一个简单的错误,我将在接下来解决这个错误。

  1. 如果您喜欢我,示例 2 不是您想要的。我发现的最佳解决方案是抓取$('#overflow').scrollTop()并将其添加到$('#offset').offset().top(即var ep = $('#offset').offset().top + $('#overflow').scrollTop())。基本上,通过将这两个变化的数字相加,它们“排序”相互抵消,为您提供div#offset元素的确切位置......或者是吗?嗯,这就是位置div#overflow很重要的地方!您必须,必须,必须考虑可滚动容器的位置。为此,请$('#overflow').offset().top$('#offset').offset().top添加$('#overflow').scrollTop(). 然后,这将考虑可滚动容器在窗口中的位置。参见示例:

https://jsfiddle.net/BrianIsSecond/yzc5ycyg/

最终,您正在寻找的是这样的:

var w = $('#overflow'),   // overflow-y:scroll;
    e = $('#offset');     // element

$('#overflow').scroll(function(){
    var wh = w.height(),                             // window height
        sp = w.scrollTop(),                          // scroll position
        ep = (e.offset().top - w.offset().top) + sp; // element position

    console.log(ep);
});

更新(10/11/17):我创建了一个函数来帮助解决这个问题。享受!

/*
function: betterOffset
hint: Allows you to calculate dynamic and static offset whether they are in a div container with overscroll or not.

            name:           type:               option:         notes:
@param      s (static)      boolean             required        default: true | set false for dynamic
@param      e (element)     string or object    required
@param      v (viewer)      string or object    optional        If you leave this out, it will use $(window) by default. What I am calling the 'viewer' is the thing that scrolls (i.e. The element with "overflow-y:scroll;" style.).

@return                  numeric
*/
function betterOffset(s, e, v) {
    // Set Defaults
        s = (typeof s == 'boolean') ? s : true;
        e = (typeof e == 'object') ? e : $(e);
        if (v != undefined) {v = (typeof v == 'object') ? v : $(v);} else {v = null;}

    // Set Variables
        var w = $(window),              // window object
            wp = w.scrollTop(),         // window position
            eo = e.offset().top;        // element offset
        if (v) {
            var vo = v.offset().top,    // viewer offset
                vp = v.scrollTop();     // viewer position
        }

    // Calculate
        if (s) {
            return (v) ? (eo - vo) + vp : eo;
        } else {
            return (v) ? eo - vo : eo - wp;
        }
}
于 2017-10-10T22:36:29.803 回答
5

我在编辑旧网站时遇到了同样的问题,我发现的解决方法是使用$(selector)[0].offsetTop而不是 $(selector).offset().top 并且它现在对我来说工作正常。

于 2018-05-13T15:32:50.800 回答
-1

在 2015 年,不应再使用“正确”答案 - 已修改偏移量。使用上述解决方案的任何代码都将不再正常工作。

解决方案:请将 jquery 升级到较新的版本(适用于 1.11.3)。或者... 将 .offset 调用改为使用 .position 。

于 2015-11-19T20:16:14.287 回答