2012-04-24 37 views

Trả lời

33

Bạn luôn có thể tính toán bù đắp, bao thanh toán ở vị trí cuộn:

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

nhưng tài liệu của tôi nằm trong iframe, xin lỗi vì không đề cập đến điểm này trong câu hỏi – gaurav

+0

Mã sẽ được đặt ở đâu, trong cửa sổ chính hoặc khung nội tuyến? – trickyzter

+0

vấn đề được giải quyết nhưng logic là ur 's, cảm ơn. – gaurav

-1

Trong năm 2015, câu trả lời 'đúng' nên không còn được sử dụng - bù đắp đã được sửa đổi. Bất kỳ mã nào sử dụng giải pháp trên sẽ không hoạt động đúng cách nữa.

Giải pháp: Vui lòng nâng cấp jquery lên phiên bản mới hơn (hoạt động trong 1.11.3). Hoặc ... thay đổi .offset call để sử dụng .position thay thế.

+2

Tôi tin rằng lời khuyên của bạn là sai ở đây, bù đắp và vị trí là độc lập của nhau và có khả năng hai giá trị khác nhau. Bù đắp liên quan đến tài liệu, Vị trí có liên quan đến phụ huynh (bù trừ). –

+0

@ m.t.bennet Bạn không nên hạ cấp vì bạn 'tin' nó sai. Tôi đã có vấn đề này chính xác, và cố định nó bằng cách sử dụng một trong hai cách tôi đã đề cập, khi giao dịch với định vị 'cố định'. Tôi nhận ra chúng là hai thứ khác nhau, và sẽ cung cấp cho các số khác nhau, nhưng nó là một thay thế nếu bạn không thể nâng cấp jquery. – Cymbals

+1

có lẽ đưa ra một bình luận giáo dục mọi người rằng đây là những tính chất khác nhau trong thực tế nhưng có thể trong thực tế cung cấp một giải pháp NẾU không sử dụng định vị cố định. Bất kể lời khuyên của bạn ở đây là không chính xác, phiên bản jQuery không quan trọng đối với câu hỏi và câu trả lời 'đúng' vẫn thích hợp. –

4

Chỉ muốn thêm câu trả lời của tôi ở đây sau khi có vấn đề tương tự:

Sau khi nhận được các hành vi nêu trên I looked at the jQuery documentation và phát hiện ra rằng

jQuery không hỗ trợ nhận được tọa độ bù đắp của ẩn yếu tố hoặc kế toán biên giới, lề hoặc đệm đặt trên phần tử cơ thể.

Yếu tố tôi đã cố gắng để bù đắp trên thực tế được đặt thành display:none; cho tôi khoản bù sai được thay đổi khi cuộn (mặc dù phần tử không di chuyển).

Vì vậy, hãy đảm bảo bạn không cố gắng bù đắp phần tử bị ẩn! hy vọng điều này sẽ giúp ai đó :)

2

Một nguyên nhân khác có thể xảy ra là nếu <body> của bạn xảy ra có CSS ​​đặt overflow-x: hidden; - điều đó hoàn toàn phá vỡ phương thức offset() của jQuery.

Trong trường hợp đó, $(window).scrollTop() luôn là 0, do đó câu trả lời được chấp nhận không hoạt động.

1

Tôi gặp sự cố rất giống với câu hỏi gốc. Việc bù đắp là kinda khó khăn. Hy vọng rằng, điều này sẽ giúp giải quyết vấn đề của bạn như nó đã làm của tôi. Tôi có 3 JSFiddles để chứng minh.

  1. Nếu bạn đang dựa các offset().top của phần tử div của bạn từ cửa sổ, bạn sẽ luôn có được một số tĩnh (tức là nếu $(window) là điều có thể cuộn và bạn có một div bên trong cửa sổ với offset().top áp dụng, div sẽ luôn có một số tĩnh). Mức chênh lệch này là số pixel chính xác mà phần tử tồn tại từ đầu của $(window) cho dù bạn cuộn xuống bao xa. Đối với mỗi JSFiddles của tôi, tôi sẽ thấy cách xa đối tượng $('div#offset') là từ đầu của vùng chứa cuộn của nó. Trong ví dụ đầu tiên này, hãy chú ý cách số không thay đổi:

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

  1. Bây giờ, cho phép nói rằng $(window) không là vùng chứa cuộn. Thay vào đó, bạn tạo một div có "overflow-y: scroll;" tập hợp thuộc tính. Trong trường hợp này, $('div#offset').offset().top hoạt động rất khác so với ví dụ trước. Bạn sẽ nhận thấy nó thay đổi khi bạn cuộn.Đối với ví dụ JSFiddle của tôi, tôi chỉ đơn giản là gói tất cả mọi thứ trong div#overflow có tập hợp thuộc tính overflow-y:scroll;. Xem ví dụ:

https://jsfiddle.net/BrianIsSecond/tcs390h6/ < --- Lưu ý rằng quá trình div # tràn không cao 100%. Tôi đã làm cho nó 100px ngắn 100%. Tôi đang sử dụng điều đó để minh họa một sai lầm dễ dàng, mà tôi sẽ giải quyết tiếp theo.

  1. Nếu bạn thích tôi, ví dụ 2 không phải là điều bạn muốn. Giải pháp tốt nhất mà tôi tìm thấy là lấy $('#overflow').scrollTop() và thêm nó vào $('#offset').offset().top (ví dụ: var ep = $('#offset').offset().top + $('#overflow').scrollTop()). Về cơ bản, bằng cách thêm hai số thay đổi này lại với nhau, chúng 'sorta' hủy lẫn nhau, cho bạn vị trí chính xác của phần tử div#offset ... hay là chúng? Vâng, đây là nơi mà vị trí của div#overflow là quan trọng! Bạn phải, phải, phải tính đến vị trí của thùng chứa có thể cuộn được. Để thực hiện việc này, hãy thực hiện $('#overflow').offset().top và trừ số này khỏi $('#offset').offset().top trước khi bạn thêm $('#overflow').scrollTop(). Điều này sau đó sẽ yếu tố ở vị trí của container có thể cuộn từ cửa sổ. Xem ví dụ:

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

Cuối cùng, những gì bạn đang tìm kiếm là một cái gì đó như thế này:

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): Tôi đã tạo một để giúp giải quyết vấn đề này. Thưởng thức!

/* 
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; 
     } 
} 
Các vấn đề liên quan