Tôi không nghĩ đây là lỗi với jQuery - dường như nó có mối quan hệ hợp pháp giữa lề H1 và phần tử cơ thể?
Vâng: lề của cơ thể và h1 là collapsing, vì vậy không chỉ h1 bị dịch chuyển theo lề mặc định của nó, mà còn cơ thể. Đây là lý do tại sao bạn đã có thể thực hiện những quan sát:
- Thiết lập một biên giới trên cơ thể giải quyết vấn đề - dường như hành vi kỳ lạ nhưng là nhất quán trên các trình duyệt? (Không phải là một giải pháp khả thi)
- Loại bỏ lề H1 giải quyết vấn đề (không phải là một giải pháp khả thi)
Dù sao, bằng cách thiết lập cơ thể để position: relative
, bạn đang nói #overlay
để hoàn toàn vị trí chính nó với cơ thể của đầu bù đắp như nguồn gốc. Kịch bản của bạn sau đó di chuyển nó tương ứng với độ lệch của #existing
. Giá trị của offsetTop
của nó có liên quan đến khung nhìn, được tính toán dựa trên vị trí của hộp này ... mà chính nó là tương đối so với h1 vì nó trực tiếp theo sau h1 trong luồng thông thường.
Do lề của các phần tử h1 và thân bị sụp đổ, chúng có cùng tỷ lệ kết xuất.Điều gì xảy ra sau đó là gấp đôi:
#existing
được đẩy xuống bởi h1 như anh chị em sau đây của nó trong luồng thông thường. Điều này làm tăng sự bù đắp của nó từ khung nhìn (trong trường hợp kiểm tra CodePen của bạn, nó là phần trên cùng của ngăn xem trước), dẫn đến số lượng offsetTop
lớn hơn.
Khi cơ thể được thiết lập để position: relative
, #overlay
kết thúc lên nhận vị trí với nguồn gốc của nó đặt cho cơ thể, mà bản thân nó cũng đã được đẩy xuống do bị sụp đổ với lề của h1. Điều này làm tăng phần bù đầu của nguồn gốc của nó, điều này sẽ không xảy ra nếu bạn không định vị cơ thể, bởi vì sau đó #overlay
sử dụng nguồn gốc của khung nhìn thay thế, không bao giờ di chuyển.
Khoảng cách của #existing
từ phía trên cùng của khung nhìn được thêm vào để bù đắp của #overlay
từ nguồn gốc của nó, mà là cơ thể, dẫn đến hiệu ứng này.
Tóm lại: do sự sụp đổ lề, trình duyệt kết thúc phải tính đến các thay đổi giảm ở cả h1 và nội dung. Các h1 ảnh hưởng đến #existing
và lần lượt của nó offsetTop
, trong khi cơ thể ảnh hưởng đến #overlay
khi bạn vị trí của nó tương đối. Vì vậy, hiệu ứng chuyển dịch xuất hiện gấp đôi.
Là một workaround nhanh chóng, bạn có thể trừ đi lợi nhuận h1 từ offsets của #existing
nhằm mục đích bù đắp #overlay
:
$("#overlay").css({
left: $("#existing").offset().left - $("h1").offset().left,
top: $("#existing").offset().top - $("h1").offset().top
})
Updated example
Chú ý rằng việc sử dụng $(document.body)
thay vì $("h1")
trên sẽ không công việc. Điều này là do sự sụp đổ lề chỉ đơn thuần là hiệu ứng dựng hình, và không thực sự ảnh hưởng đến độ lệch của cơ thể cho đến khi bạn tạo ra biên độ riêng của nó (nói cách khác, lề cơ thể vẫn tính bằng không, vì vậy DOM vẫn không còn khôn ngoan hơn).
Không liên quan trực tiếp đến vấn đề trước mắt, nhưng giá trị giải quyết anyway:
- Khoản chênh lệch H1 dường như thay đổi nơi 0,0 cơ thể được tính từ - mặc dù nền trên cơ thể mở rộng tất cả các cách để cạnh, và đó là offsetTop báo cáo tài sản 0
Phần đầu tiên và cuối cùng của điểm này có ong n giải quyết ở trên.
Đối với nền nội dung: trong khi nó dường như mở rộng tất cả các cách để cạnh, nền mở rộng này không thực sự thuộc về cơ thể - nó được truyền từ cơ thể đến, và do đó thuộc về, phần tử gốc (html) và chế độ xem. Xem this answer để được giải thích.
Oh và điều này:
Đây không phải là một lỗi vì hành vi này là nhất quán trên FF, Chrome, IE9 và Safari trên Win7.
Làm tôi mỉm cười.Bởi vì một lần, ai đó nói đúng.
Gắn dấu sao này vì tôi vô tình ở lại quá lâu để tìm ra điều này. Cảm ơn. Tôi thực sự nên nhấn bao giờ :) – BoltClock