jQuery có được vị trí của một phần tử so với cửa sổ


168

Đưa ra một ID DOM HTML, làm thế nào để có được vị trí của một phần tử so với cửa sổ trong JavaScript / JQuery? Điều này không giống với liên quan đến tài liệu cũng như phần bù cha vì phần tử có thể nằm trong iframe hoặc một số phần tử khác. Tôi cần lấy vị trí màn hình của hình chữ nhật của phần tử (như ở vị trí và kích thước) vì nó hiện đang được hiển thị. Các giá trị âm được chấp nhận nếu phần tử hiện ở ngoài màn hình (đã được cuộn ra).

Cái này dành cho ứng dụng iPad (WebKit / WebView). Bất cứ khi nào người dùng chạm vào một liên kết đặc biệt trong một UIWebView, tôi phải mở một giao diện popover hiển thị thêm thông tin về liên kết. Chế độ xem popover cần hiển thị một mũi tên quay lại phần màn hình gọi nó.

Câu trả lời:


264

Ban đầu, lấy vị trí .offset của phần tử và tính toán vị trí tương đối của nó đối với cửa sổ

Tham khảo :
1. offset
2. cuộn
3. scrollTop

Bạn có thể thử nó tại fiddle này

Sau vài dòng mã giải thích làm thế nào điều này có thể được giải quyết

khi sự kiện .scroll được thực hiện, chúng tôi tính toán vị trí tương đối của phần tử đối với đối tượng cửa sổ

$(window).scroll(function () {
    console.log(eTop - $(window).scrollTop());
});

Khi cuộn được thực hiện trong trình duyệt, chúng tôi gọi chức năng xử lý sự kiện ở trên

đoạn mã


function log(txt) {
  $("#log").html("location : <b>" + txt + "</b> px")
}

$(function() {
  var eTop = $('#element').offset().top; //get the offset top of the element
  log(eTop - $(window).scrollTop()); //position of the ele w.r.t window

  $(window).scroll(function() { //when window is scrolled
    log(eTop - $(window).scrollTop());
  });
});
#element {
  margin: 140px;
  text-align: center;
  padding: 5px;
  width: 200px;
  height: 200px;
  border: 1px solid #0099f9;
  border-radius: 3px;
  background: #444;
  color: #0099d9;
  opacity: 0.6;
}
#log {
  position: fixed;
  top: 40px;
  left: 40px;
  color: #333;
}
#scroll {
  position: fixed;
  bottom: 10px;
  right: 10px;
  border: 1px solid #000;
  border-radius: 2px;
  padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="log"></div>

<div id="element">Hello
  <hr>World</div>
<div id="scroll">Scroll Down</div>


1
Cảm ơn kịch bản. Điều này dường như hoạt động trong máy tính để bàn nhưng không hoạt động trên iPad. Có vẻ như $ (window) .scrollTop () và $ (window) .scrollLeft () không được cập nhật trong iPad. Bạn có thể dùng thử phiên bản của tôi qua jsbin.com/oghua4/5
adib

2
Chúng không được cập nhật trên iPad vì bản thân cửa sổ không cuộn - người dùng đang cuộn quanh bên trong cửa sổ. Dù sao đó cũng là một trang web cơ bản, không chắc chắn về một trang web nhắm mục tiêu đến thiết bị di động, có thể có nhiều tùy chọn hơn ở đó.
eselk

Điều này sẽ thất bại khi một phần tử nằm trong một phần tử có thể cuộn khác, e. g. <div>. Bạn chỉ xem xét cuộn tài liệu chứ không phải cuộn phần tử khác.
ygoe

71

Hãy thử hộp giới hạn. Thật đơn giản:

var leftPos  = $("#element")[0].getBoundingClientRect().left   + $(window)['scrollLeft']();
var rightPos = $("#element")[0].getBoundingClientRect().right  + $(window)['scrollLeft']();
var topPos   = $("#element")[0].getBoundingClientRect().top    + $(window)['scrollTop']();
var bottomPos= $("#element")[0].getBoundingClientRect().bottom + $(window)['scrollTop']();

7
getBoundingClientRect () là câu trả lời cho vấn đề này. Cảm ơn bạn prograhammer.
Vlad Lego

1
Điều này làm việc tốt. Tôi chỉ cần bao gồm một số mã để sửa lỗi cuộn của mình, ngoài scrollLetf và scrollTop: topPos = topPos - $ (window) .scrollTop (); leftPos = leftPos - $ (cửa sổ) .scrollLeft (); rightPos = rightPos - $ (cửa sổ) .scrollTop (); bottomPos = bottomPos - $ (cửa sổ) .scrollLeft ();
Cesar

1
ngày mà mọi người sẽ học cách kết thúc mọi thứ theo một phương pháp hữu ích tốt đẹp
mmm

@Noldorin Hỗ trợ trên IE / Edge có vẻ tốt với tôi: caniuse.com/#feat=getboundingclientrect
prograhammer

1
@prograhammer Xấu của tôi, bạn nói đúng. Tôi đã đọc điều này trên một số trang web và lấy từ của nó theo mệnh giá ... hóa ra nó đã sai (hoặc ít nhất là không hoạt động trên IE cũ).
Noldorin

6
function getWindowRelativeOffset(parentWindow, elem) {
        var offset = {
            left : 0,
            top : 0
        };
        // relative to the target field's document
        offset.left = elem.getBoundingClientRect().left;
        offset.top = elem.getBoundingClientRect().top;
        // now we will calculate according to the current document, this current
        // document might be same as the document of target field or it may be
        // parent of the document of the target field
        var childWindow = elem.document.frames.window;
        while (childWindow != parentWindow) {
            offset.left = offset.left + childWindow.frameElement.getBoundingClientRect().left;
            offset.top = offset.top + childWindow.frameElement.getBoundingClientRect().top;
            childWindow = childWindow.parent;
        }
        return offset;
    };

bạn có thể gọi nó như thế này

getWindowRelativeOffset(top, inputElement);

Tôi chỉ tập trung vào IE theo yêu cầu của mình nhưng tương tự có thể được thực hiện cho các trình duyệt khác


4

Điều này nghe có vẻ giống như bạn muốn có một chú giải công cụ cho liên kết được chọn. Có nhiều công cụ jQuery, hãy thử jQuery qTip . Nó có rất nhiều tùy chọn và dễ dàng thay đổi phong cách.

Mặt khác, nếu bạn muốn tự làm điều này, bạn có thể sử dụng jQuery .position(). Thông tin thêm về .position()là trên http://api.jquery.com/poseition/

$("#element").position(); sẽ trả về vị trí hiện tại của một phần tử so với phần tử bù.

Ngoài ra còn có jQuery .offset (); sẽ trả về vị trí liên quan đến tài liệu.


2
Nó không thực sự là một tooltip, nhưng để mở một widget UI gốc để thêm chú thích.
adib


1
    function trbl(e, relative) {
            var r = $(e).get(0).getBoundingClientRect(); relative = $(relative);

            return {
                    t : r.top    + relative['scrollTop'] (),
                    r : r.right  + relative['scrollLeft'](),
                    b : r.bottom + relative['scrollTop'] (),
                    l : r.left   + relative['scrollLeft']() 

            }
    }

    // Example
    trbl(e, window);

1

Hãy thử điều này để có được vị trí của một yếu tố liên quan đến cửa sổ.

        $("button").click(function(){
            var offset = $("#simplebox").offset();
            alert("Current position of the box is: (left: " + offset.left + ", top: " + offset.top + ")");
        });
    #simplebox{
        width:150px;
        height:100px;
        background: #FBBC09;
        margin: 150px 100px;
    }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button">Get Box Position</button>
    <p><strong>Note:</strong> Play with the value of margin property to see how the jQuery offest() method works.</p>
    <div id="simplebox"></div>

Xem thêm @ Nhận vị trí của một phần tử so với tài liệu bằng jQuery

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.