ChatGPT解决这个技术问题 Extra ChatGPT

jQuery get the location of an element relative to window

Given an HTML DOM ID, how to get an element's position relative to the window in JavaScript/JQuery? This is not the same as relative to the document nor offset parent since the element may be inside an iframe or some other elements. I need to get the screen location of the element's rectangle (as in position and dimension) as it is currently being displayed. Negative values are acceptable if the element is currently off-screen (have been scrolled off).

This is for an iPad (WebKit / WebView) application. Whenever the user taps on a special link in an UIWebView, I am supposed to open a popover view that displays further information about the link. The popover view needs to display an arrow that points back to the part of the screen that invokes it.


j
jterry

Initially, Grab the .offset position of the element and calculate its relative position with respect to window

Refer :
1. offset
2. scroll
3. scrollTop

You can give it a try at this fiddle

Following few lines of code explains how this can be solved

when .scroll event is performed, we calculate the relative position of the element with respect to window object

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

when scroll is performed in browser, we call the above event handler function

code snippet

function log(txt) { $("#log").html("location : " + txt + " 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; }

Hello
World
Scroll Down


Thanks for the script. This seems to work in the desktop but doesn't work on the iPad. It seems that $(window).scrollTop() and $(window).scrollLeft() doesn't get updated in the iPad. You can try my version via jsbin.com/ogiwu4/5
They don't get updated on the iPad because the window itself isn't scrolling -- the user is scrolling around inside the window. That's the case for a basic website anyway, not sure about one that targets mobile devices, probably have more options there.
This should fail when an element is within another scrollable element, e. g. <div>. You only consider the document scrolling but not the other element scrolling.
p
prograhammer

Try the bounding box. It's simple:

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']();

getBoundingClientRect() is the answer to this problem. Thank you prograhammer.
this worked good. I just had to include some code to fix my scroll, in addition to your scrollLetf and scrollTop: topPos = topPos - $(window).scrollTop(); leftPos = leftPos - $(window).scrollLeft(); rightPos = rightPos - $(window).scrollTop(); bottomPos = bottomPos - $(window).scrollLeft();
the day when people are going to learn to wrap things up in a nice useful method
@Noldorin The support on IE/Edge looks good to me: caniuse.com/#feat=getboundingclientrect
@prograhammer My bad, you're right. I read this on some website and took its word at face value... turns out it was wrong (or least only doesn't work on old IE).
M
MrSingh
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;
};

you can call it like this

getWindowRelativeOffset(top, inputElement);

I focus for IE only as per my requirement but similar can be done for other browsers


B
Bob Stein

TL;DR

headroom_by_jQuery = $('#id').offset().top - $(window).scrollTop();

headroom_by_DOM = $('#id')[0].getBoundingClientRect().top;   // if no iframe

.getBoundingClientRect() appears to be universal. .offset() and .scrollTop() have been supported since jQuery 1.2. Thanks @user372551 and @prograhammer. To use DOM in an iframe see @ImranAnsari's solution.


A
AlexB

This sounds more like you want a tooltip for the link selected. There are many jQuery tooltips, try out jQuery qTip. It has a lot of options and is easy to change the styles.

Otherwise if you want to do this yourself you can use the jQuery .position(). More info about .position() is on http://api.jquery.com/position/

$("#element").position(); will return the current position of an element relative to the offset parent.

There is also the jQuery .offset(); which will return the position relative to the document.


Its not really a tooltip, but to open a native UI widget to add annotations.
K
Ketan Savaliya

Try this to get the location of an element relative to window.

$("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; }

Note: Play with the value of margin property to see how the jQuery offest() method works.

See more @ Get the position of an element relative to the document with jQuery


M
MrSingh
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);