2012-04-24 57 views
21
var offset = $(selector).offset(); 

如果我們上下滾動頁面,偏移變量的值會發生變化,我希望確保和固定的偏移值,同時保持「選擇器」的默認位置(靜態) 。我怎樣才能做到這一點?通過滾動頁面jquery偏移值的變化

回答

33

你總是可以計算偏移量,保理在滾動位置:

var offset_t = $(selector).offset().top - $(window).scrollTop(); 
var offset_l = $(selector).offset().left - $(window).scrollLeft(); 
+0

但我的文檔在iframe中,對不起提及這個問題 – gaurav 2012-04-24 12:50:29

+0

代碼放在父窗口或iframe中的位置? – trickyzter 2012-04-24 13:09:42

+0

問題已解決,但邏輯是你的,謝謝。 – gaurav 2012-04-24 17:37:13

-1

在2015年,「正確」的答案應該不再使用 - 偏移已被修改。任何使用上述解決方案的代碼將不再正常工作。

解決方案:請將jquery升級到更新的版本(在1.11.3中運行)。 或者...更改.offset調用以代替使用.position。

+2

我相信你的建議在這裏是錯誤的,偏移量和位置是相互獨立的,可能有兩個不同的值。偏移量與文檔有關,位置相對於(偏移量)父項。 – 2015-12-04 02:43:26

+0

@ m.t.bennet你不應該降級,因爲你'相信'它是錯誤的。我有這個確切的問題,並在處理「固定」定位時,使用我提到的任何一種方式修復它。我意識到他們是兩個不同的東西,並會給出不同的數字,但是如果你不能升級jQuery,它是一種選擇。 – Cymbals 2015-12-04 21:20:02

+1

也許會發表評論,教育人們這些實際上是不同的屬性,但實際上如果不使用固定位置,可能會提供解決方案。無論你的建議是否正確,jQuery版本對於這個問題都不重要,「正確的」答案仍然適用。 – 2015-12-05 01:10:41

4

只是想有同樣的問題後,在這裏補充我的回答:

獲得上述I looked at the jQuery documentation描述和行爲後發現,

jQuery的不支持獲取的隱藏元素的偏移座標或者考慮在body元素上設置的邊框,邊距或填充。

元素我試圖讓在事實上設定的偏移display:none;給我一個虛假的偏移滾動時(即使該元素不動)的改變。

所以請確保你沒有試圖獲得隱藏元素的偏移量!希望這可以幫助別人:)

2

另一個潛在的原因是,如果您的<body>碰巧有CSS設置overflow-x: hidden; - 這完全違反了jQuery的offset()方法。

在這種情況下,$(window).scrollTop()始終爲0,因此接受的答案不起作用。

1

我有一個非常類似的問題,原來的問題。抵消是有點棘手。希望這將有助於解決你的問題,因爲它是我的。我有3個JSFiddles來演示。

  1. 如果你從窗口基礎的div元素的offset().top,你總是會得到一個靜態的數字(即如果$(window)是事情,滾動,你有offset().top窗口應用中一個div中, div將始終有一個靜態數字)。無論向下滾動多少,此偏移量都是從$(window)的頂部開始的元素的確切像素數。對於我的每個JSFiddles,我會看到對象$('div#offset')距離它的滾動容器的頂部多遠。在此第一實例中,請注意數量不會改變:

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

  • 現在,讓我們說,$(window)不是容器滾動。你可以創建一個具有「overflow-y:scroll」的div。屬性集。在這種情況下,$('div#offset').offset().top的行爲與前面的例子非常不同。當您滾動時,您會注意到它會發生變化。對於我的JSFiddle示例,我簡單地將div#overflow中的所有內容都包含在overflow-y:scroll;屬性集中。請參閱示例:
  • https://jsfiddle.net/BrianIsSecond/tcs390h6/ < ---請注意,div#溢出不是100%高。我把它做成了100px的100px。我用這個來說明一個容易犯的錯誤,接下來我會解決這個錯誤。

    1. 如果你喜歡我,例2不是你想要的。我找到的最佳解決方案是抓取$('#overflow').scrollTop()並將其添加到$('#offset').offset().top(即var ep = $('#offset').offset().top + $('#overflow').scrollTop())。基本上,通過將這兩個不斷變化的數字加在一起,他們就會相互抵消,給出你的元素的確切位置......或者他們呢?那麼,這就是div#overflow的位置很重要!必須必須考慮到可滾動容器的位置。爲此,請在添加$('#overflow').scrollTop()之前將$('#overflow').offset().top$('#offset').offset().top中減去。這將影響窗口中可滾動容器的位置。見例如:

    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); 
    }); 
    

    UPDATE(17年10月11日):我創建了一個功能來幫助解決這個問題。請享用!

    /* 
    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; 
         } 
    }