通过滚动页面更改 jquery 偏移值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10297688/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
jquery offset values changes by scrolling the page
提问by Gaurav
var offset = $(selector).offset();
The values of offset variable changes if we scroll the page up and down, i want the exact and fixed offset values while keeping the position of the "selector" default(static).How can i do this?
如果我们上下滚动页面,偏移变量的值会发生变化,我想要精确和固定的偏移值,同时保持“选择器”的位置默认(静态)。我该怎么做?
回答by trickyzter
You could always calculate the offset, factoring in the scroll position:
您总是可以计算偏移量,将滚动位置考虑在内:
var offset_t = $(selector).offset().top - $(window).scrollTop();
var offset_l = $(selector).offset().left - $(window).scrollLeft();
回答by m.t.bennett
Just wanted to add my answer here after having the same issues:
在遇到相同的问题后,只想在这里添加我的答案:
After getting the behaviour described above I looked at the jQuery documentationand discovered that
在获得上述行为后,我查看了 jQuery 文档并发现
jQuery does not support getting the offset coordinates of hiddenelements or accounting for borders, margins, or padding set on the body element.
jQuery 不支持获取隐藏元素的偏移坐标,也不支持在 body 元素上设置边框、边距或填充。
The element I was trying to get the offset of was in fact set to display:none;
giving me a false offset which changed when scrolling (even though the element didn't move).
我试图获取偏移量的元素实际上设置为display:none;
给我一个错误的偏移量,该偏移量在滚动时发生了变化(即使元素没有移动)。
So make sure you're not trying to get an offset of a hidden element! hope this helps someone :)
因此,请确保您没有尝试获取隐藏元素的偏移量!希望这对某人有所帮助:)
回答by Nathan Friedly
One other potential cause is if your <body>
happens to have CSS that sets overflow-x: hidden;
- that completely breaks jQuery's offset()
method.
另一个潜在原因是,如果您<body>
碰巧设置了 CSS overflow-x: hidden;
- 这完全破坏了 jQuery 的offset()
方法。
In that case, $(window).scrollTop()
is always 0, so the accepted answer does not work.
在这种情况下,$(window).scrollTop()
始终为 0,因此接受的答案不起作用。
回答by Brian
I had a very similar issue to the original question. The offset is kinda tricky. Hopefully, this will help solve your problems as it did mine. I have 3 JSFiddles to demonstrate.
我有一个与原始问题非常相似的问题。偏移有点棘手。希望这将有助于解决您的问题,就像我的问题一样。我有 3 个 JSFiddles 来演示。
- If you are basing the
offset().top
of your div element from the window, you will always get a static number (i.e. if the$(window)
is the thing that scrolls and you have a div inside the window withoffset().top
applied, the div will always have a static number). This offset is the exact number of pixels the element exists from the top of the$(window)
no matter how far down you scroll. For each of my JSFiddles, I'll see how far down the object$('div#offset')
is from the top of it's scrolling container. In this first example, notice how the number doesn't change:
- 如果您将
offset().top
div 元素作为窗口的基础,您将始终获得一个静态数字(即,如果$(window)
div 是滚动的东西并且您在应用了窗口内offset().top
的 div,则该 div 将始终具有一个静态数字)。$(window)
无论您向下滚动多远,此偏移量都是元素距顶部的确切像素数。对于我的每个 JSFiddles,我会看到对象$('div#offset')
离它的滚动容器顶部有多远。在第一个示例中,请注意数字是如何不变的:
https://jsfiddle.net/BrianIsSecond/ehkgh2gu/
https://jsfiddle.net/BrianIsSecond/ehkgh2gu/
- Now, lets say that the
$(window)
isn't the container that scrolls. You instead create a div that has an "overflow-y:scroll;" attribute set. In this case, the$('div#offset').offset().top
acts very differently than the previous example. You'll notice it changes as you scroll. For my JSFiddle example, I simply wrapped everything indiv#overflow
that hasoverflow-y:scroll;
attribute set. See example:
- 现在,让我们说这
$(window)
不是滚动的容器。您改为创建一个具有“溢出-y:滚动;”的 div。属性集。在这种情况下,其$('div#offset').offset().top
行为与前一个示例非常不同。当您滚动时,您会注意到它发生了变化。对于我的 JSFiddle 示例,我只是将所有内容都包含在div#overflow
具有overflow-y:scroll;
属性集的内容中。见示例:
https://jsfiddle.net/BrianIsSecond/tcs390h6/<--- Note too that div#overflow isn't 100% tall. I made it 100px short of 100%. I am using that to illustrate an easy mistake, which I will address next.
https://jsfiddle.net/BrianIsSecond/tcs390h6/<--- 还要注意 div#overflow 不是 100% 高。我使它比 100% 少了 100px。我用它来说明一个简单的错误,我将在接下来解决这个错误。
- If your like me, example 2 isn't what you were wanting. The best solution I have found is to grab
$('#overflow').scrollTop()
and add it to$('#offset').offset().top
(i.e.var ep = $('#offset').offset().top + $('#overflow').scrollTop()
). Basically, by adding these two changing numbers together, they 'sorta' cancel each other out, giving you the exact position of thediv#offset
element... or do they? Well, this is where the position of thediv#overflow
is important! You must, must, must take into account the position of the scrollable container. To do this, take$('#overflow').offset().top
and subtract it from$('#offset').offset().top
before you add$('#overflow').scrollTop()
. This will then factor in the position of the scrollable container from the window. See example:
- 如果您喜欢我,示例 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/
https://jsfiddle.net/BrianIsSecond/yzc5ycyg/
Ultimately, what you are looking for is something like this:
最终,您正在寻找的是这样的:
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);
});
UPDATE (10/11/17): I've created a function to help solve this problem. Enjoy!
更新 (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;
}
}
回答by mayank mandloi
I am having the same problem while editing a old website the workaround I find out is to use $(selector)[0].offsetTopinstead of $(selector).offset().top and it is working fine for me right now.
我在编辑旧网站时遇到了同样的问题,我发现的解决方法是使用$(selector)[0].offsetTop而不是 $(selector).offset().top ,它现在对我来说很好用。
回答by Cymbals
In 2015, the 'correct' answer should no longer be used - offset has been modified. Any code that used the above solution will no longer work properly.
2015 年,不应再使用“正确”答案 - 已修改偏移量。使用上述解决方案的任何代码将不再正常工作。
Solution: Please upgrade jquery to a newer version (works in 1.11.3). Or... change .offset call to use .position instead.
解决方案:请将 jquery 升级到较新的版本(适用于 1.11.3)。或者...更改 .offset 调用以使用 .position 代替。