jQuery pobiera lokalizację elementu względem okna

168

Biorąc pod uwagę identyfikator HTML DOM, jak uzyskać pozycję elementu względem okna w JavaScript / JQuery? To nie to samo, co w odniesieniu do dokumentu ani offsetowego elementu nadrzędnego, ponieważ element może znajdować się wewnątrz elementu iframe lub innych elementów. Muszę uzyskać lokalizację na ekranie prostokąta elementu (jak w pozycji i wymiarach), tak jak jest aktualnie wyświetlany. Wartości ujemne są dopuszczalne, jeśli element jest obecnie poza ekranem (zostały przewinięte).

Dotyczy to aplikacji na iPada (WebKit / WebView). Za każdym razem, gdy użytkownik stuknie w specjalne łącze w elemencie UIWebView, mam otworzyć widok podręczny, który wyświetla dalsze informacje o tym łączu. Widok podręczny musi wyświetlać strzałkę wskazującą z powrotem do części ekranu, która go wywołuje.

adib
źródło

Odpowiedzi:

264

Początkowo chwyć .offset pozycję elementu i oblicz jego względną pozycję w stosunku do okna

Patrz :
1. offset
2. scroll
3. scrollTop

Możesz spróbować na tych skrzypcach

Poniższe kilka wierszy kodu wyjaśnia, jak można to rozwiązać

przy wykonywaniu zdarzenia .scroll obliczamy względne położenie elementu względem obiektu okna

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

kiedy przewijanie jest wykonywane w przeglądarce, wywołujemy powyższą funkcję obsługi zdarzeń

fragment kodu


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>

jterry
źródło
1
Dzięki za scenariusz. Wydaje się, że działa na pulpicie, ale nie działa na iPadzie. Wygląda na to, że $ (window) .scrollTop () i $ (window) .scrollLeft () nie są aktualizowane na iPadzie. Możesz wypróbować moją wersję przez jsbin.com/ogiwu4/5
adib
2
Nie są aktualizowane na iPadzie, ponieważ samo okno nie przewija się - użytkownik przewija się w oknie. Tak jest w przypadku podstawowej witryny internetowej, nie jestem pewien co do takiej, która jest kierowana na urządzenia mobilne, prawdopodobnie ma tam więcej opcji.
eselk
Powinno to się nie powieść, gdy element znajduje się w innym przewijalnym elemencie, np. sol. <div>. Bierzesz pod uwagę tylko przewijanie dokumentu, ale nie przewijanie innych elementów.
ygoe
71

Wypróbuj obwiednię. To proste:

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']();
prograhammer
źródło
7
GetBoundingClientRect () jest odpowiedzią na ten problem. Dziękuję prograhammer.
Vlad Lego
1
to działało dobrze. Musiałem tylko dołączyć jakiś kod, aby naprawić mój scroll, oprócz twoich scrollLetf i scrollTop: topPos = topPos - $ (okno) .scrollTop (); leftPos = leftPos - $ (okno) .scrollLeft (); rightPos = rightPos - $ (okno) .scrollTop (); bottomPos = bottomPos - $ (okno) .scrollLeft ();
Cesar
1
dzień, w którym ludzie nauczą się podsumowywać wszystko w ładną, przydatną metodę
mmm.
@Noldorin Wsparcie dla IE / Edge wygląda dla mnie dobrze: caniuse.com/#feat=getboundingclientrect
prograhammer
1
@prograhammer My bad, masz rację. Przeczytałem to na jakiejś stronie i uwierzyłem na słowo ... okazuje się, że było źle (a przynajmniej nie działa tylko na starym IE).
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;
    };

możesz to tak nazwać

getWindowRelativeOffset(top, inputElement);

Skupiam się na IE tylko zgodnie z moimi wymaganiami, ale podobnie można zrobić dla innych przeglądarek

Imran Ansari
źródło
4

To brzmi bardziej tak, jakbyś potrzebował podpowiedzi dla wybranego łącza. Istnieje wiele podpowiedzi jQuery, wypróbuj jQuery qTip . Ma wiele opcji i łatwo jest zmieniać style.

W przeciwnym razie, jeśli chcesz to zrobić samodzielnie, możesz użyć jQuery .position(). Więcej informacji na temat .position()znajduje się na http://api.jquery.com/position/

$("#element").position(); zwróci bieżącą pozycję elementu względem elementu macierzystego odsunięcia.

Istnieje również jQuery .offset (); która zwróci pozycję względem dokumentu.

jhanifen
źródło
2
To naprawdę nie jest podpowiedź, ale otwarcie natywnego widżetu interfejsu użytkownika w celu dodania adnotacji.
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);
mmm
źródło
1

Spróbuj tego, aby uzyskać położenie elementu względem okna.

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

Zobacz więcej @ Uzyskaj pozycję elementu względem dokumentu za pomocą jQuery

Ketan Savaliya
źródło