offsetTop so với jQuery.offset (). top


82

Tôi đã đọc nó offsetLeftoffsetTopkhông hoạt động bình thường trong tất cả các trình duyệt. jQuery.offset()phải cung cấp một sự trừu tượng cho điều này để cung cấp giá trị chính xác xbrowser.

Những gì tôi đang cố gắng làm là lấy tọa độ nơi một phần tử được nhấp vào so với phía trên bên trái của phần tử.

Vấn đề là jQuery.offset().topthực sự đang cho tôi một giá trị thập phân trong FFX 3.6 (trong IE và Chrome, hai giá trị khớp với nhau).

Điều này cho thấy vấn đề. Nếu bạn bấm vào hình dưới cùng, jQuery.offset().toptrả về 327,5, nhưng offsetToptrả về 328.

Tôi muốn nghĩ rằng nó offset()đang trả về giá trị chính xác và tôi nên sử dụng nó vì nó sẽ hoạt động trên các trình duyệt. Tuy nhiên, mọi người rõ ràng không thể nhấp vào số thập phân của pixel. Có phải cách thích hợp để xác định giá trị bù đúng với Math.round()độ lệch mà jQuery đang trả về? Tôi nên sử dụng offsetTopthay thế hay một số phương pháp hoàn toàn khác?

Câu trả lời:


15

Tôi nghĩ bạn đúng khi nói rằng mọi người không thể nhấp vào nửa pixel, vì vậy, cá nhân tôi sẽ sử dụng bù đắp jQuery làm tròn ...


4
jQuery bù đắp là lỗi khi CSS zoom được sử dụng
Mladen Janjetovic

76

Đây là những gì jQuery API Doc nói về .offset():

Lấy tọa độ hiện tại của phần tử đầu tiên hoặc đặt tọa độ của mọi phần tử, trong tập hợp các phần tử đã so khớp, liên quan đến tài liệu .

Đây là những gì MDN Web API nói về .offsetTop:

offsetTop trả về khoảng cách của phần tử hiện tại so với đỉnh của nút offsetParent

Đây là những gì jQuery v.1.11 .offset()về cơ bản làm khi lấy các coords:

var box = { top: 0, left: 0 };

// BlackBerry 5, iOS 3 (original iPhone)
if ( typeof elem.getBoundingClientRect !== strundefined ) {
  box = elem.getBoundingClientRect();
}
win = getWindow( doc );
return {
  top: box.top  + ( win.pageYOffset || docElem.scrollTop )  - ( docElem.clientTop  || 0 ),
  left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
};
  • pageYOffset trực quan cho biết trang đã cuộn bao nhiêu
  • docElem.scrollTop là dự phòng cho IE <9 (BTW không được hỗ trợ trong jQuery 2)
  • docElem.clientTop là chiều rộng của đường viền trên cùng của một phần tử (tài liệu trong trường hợp này)
  • elem.getBoundingClientRect()nhận các coords liên quan đến khung nhìn tài liệu (xem nhận xét). Nó có thể trả về giá trị phân số, vì vậy đây là nguồn gốc của lỗi của bạn. Nó cũng có thể gây ra lỗi trong IE <8 khi trang được phóng to. Để tránh các giá trị phân số, hãy thử tính toán vị trí theo cách lặp lại

Phần kết luận

  • Nếu bạn muốn coords liên quan đến nút cha , hãy sử dụng element.offsetTop. Thêm element.scrollTopnếu bạn muốn tính đến việc cuộn phụ huynh. (hoặc sử dụng jQuery .position () nếu bạn yêu thích thư viện đó)
  • Nếu bạn muốn coords liên quan đến việc sử dụng khung nhìnelement.getBoundingClientRect().top . Thêm window.pageYOffsetnếu bạn muốn tính đến việc cuộn tài liệu. Bạn không cần phải trừ tài liệu clientTopnếu tài liệu không có đường viền (thường là không có), vì vậy bạn có vị trí so với tài liệu
  • Trừ element.clientTopnếu bạn không coi đường viền phần tử là một phần của phần tử

Element.getBoundingClientRect()mang đến cho các vị trí tương đối so với khung nhìn , không phải là tài liệu
Klaus

@Klaus: bạn có thể giải thích sự khác biệt chính xác là gì không?
Jan Turoň

2
@ JanTuroň: Sự khác biệt là nó liên quan đến đầu cửa sổ trình duyệt không phải là tài liệu "true top". Có nghĩa là nó sẽ trả về giá trị âm nếu bạn cuộn nó lên trên cùng của cửa sổ chẳng hạn.
Ryan Badour

5

Thử đi: parseInt(jQuery.offset().top, 10)


Tôi ước gì có lý do đằng sau nó, vì vậy tôi có thể bỏ phiếu cho bạn
Kick Buttowski

2

Có thể offsetcó thể là một số không phải là số nguyên, sử dụng emlàm đơn vị đo lường, tương đối font-sizestrong %.

Tôi cũng đưa ra giả thuyết rằng số offsetcó thể không phải là một số nguyên khi zoomkhông phải là số nguyên 100%nhưng điều đó phụ thuộc vào cách trình duyệt xử lý việc mở rộng quy mô.


2
. nếu isnt zoom 100%, bù đắp () hàng đầu sẽ cung cấp cho bạn một loạt các vấn đề khác ... bugs.jquery.com/ticket/8362
commonpike

-1

Bạn có thể sử dụng parseInt(jQuery.offset().top)để luôn sử dụng intgiá trị Số nguyên (nguyên thủy - ) trên tất cả các trình duyệt.


1
Vòng parseInt () có tăng gấp đôi hay cắt bớt chúng không?
Thuốc nổ,

Nó sẽ chỉ lấy phần nguyên của số và nó sẽ giống nhau trên tất cả các trình duyệt.
ShankarSangoli,

OP tuyên bố rằng trong một trình duyệt, nó cho 327,5 trong khi trong một trình duyệt khác, nó cho 328. Vì vậy, nếu bạn chỉ lấy phần nguyên (cắt ngắn), chính OP là một ví dụ về việc nó không giống nhau trên tất cả các trình duyệt. Đối với ví dụ này, ít nhất nó sẽ phải làm tròn cho cả hai để cho cùng một số.
Jimbo Jonny
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.