2012-04-24 12 views

Odpowiedz

33

Zawsze można obliczyć offset, faktoring w pozycji przewijania:

var offset_t = $(selector).offset().top - $(window).scrollTop(); 
var offset_l = $(selector).offset().left - $(window).scrollLeft(); 
+0

ale mój dokument jest w iframe, przepraszam za nie wspomnieć tego punktu w pytaniu – gaurav

+0

Gdzie będzie kod zostać objęte okna nadrzędnego lub iframe? – trickyzter

+0

problem rozwiązany, ale logika jest urs, dzięki. – gaurav

-1

W 2015 roku „poprawny” odpowiedź nie powinna być dłużej używana - przesunięcie został zmodyfikowany. Każdy kod korzystający z powyższego rozwiązania przestanie działać poprawnie.

Rozwiązanie: Zaktualizuj jquery do nowszej wersji (działa w wersji 1.11.3). Lub ... zmień wywołanie wywołania, aby użyć opcji .position.

+2

Uważam, że twoja rada jest tutaj zła, offset i pozycja są niezależne od siebie i potencjalnie dwie różne wartości. Przesunięcie odnosi się do dokumentu, Pozycja jest względna względem rodzica (przesunięcia). –

+0

@ m.t.bennet Nie powinieneś obniżać oceny, ponieważ "wierzysz", że to jest złe. Miałem ten dokładny problem i naprawiłem go w dowolny sposób, o którym wspomniałem, kiedy zajmowałem się "ustalonym" pozycjonowaniem. Rozumiem, że są to dwie różne rzeczy i podają różne liczby, ale jest to alternatywa, jeśli nie można zaktualizować jquery. – Cymbals

+1

Być może umieszczając komentarz ucząc ludzi, że są to w rzeczywistości różne właściwości, ale mogą w rzeczywistości oferować rozwiązanie, jeśli nie używają ustalonego pozycjonowania. Niezależnie od twojej porady tutaj jest niepoprawny, wersja jQuery nie ma znaczenia w odniesieniu do pytania, a "poprawna" odpowiedź jest nadal odpowiednia. –

4

Chciałem tylko dodać moją odpowiedź tutaj po te same problemy:

Po zdobyciu zachowanie opisane powyżej I looked at the jQuery documentation i odkrył, że

jQuery nie obsługuje coraz offsetowych współrzędne ukrytych elementów lub obliczyć granice, marginesy lub dopełnienie ustawione na elemencie body.

Element starałem się uzyskać przesunięcie został w rzeczywistości ustawiony display:none; dając mi fałszywy przesunięcie który zmienił podczas przewijania (chociaż element nie drgnął).

Upewnij się więc, że nie próbujesz uzyskać przesunięcia ukrytego elementu! Mam nadzieję, że to pomogło komuś :)

2

Inną potencjalną przyczyną jest to, że Twój <body> ma CSS, który ustawia overflow-x: hidden; - całkowicie przerywa metodęjQuery.

W takim przypadku $(window).scrollTop() ma zawsze wartość 0, więc zaakceptowana odpowiedź nie działa.

1

Miałem bardzo podobny problem z pierwotnym pytaniem. Przesunięcie jest trochę trudne. Mam nadzieję, że to pomoże rozwiązać twoje problemy, tak jak to zrobiłem. Mam 3 JSFiddles do wykazania.

  1. Jeśli oparcie offset().top swojego elementu div z okna, zawsze możesz liczyć na szereg statycznych (czyli jeśli $(window) jest rzeczą, która przewija i masz div wewnątrz okna z offset().top stosowanej The div zawsze będzie miał numer statyczny). Przesunięcie to to dokładna liczba pikseli, które element istnieje od góry, bez względu na to, jak daleko w dół przewijasz. Dla każdego z moich JSFiddles zobaczę, jak daleko od obiektu znajduje się przewijany obiekt $('div#offset'). W tym pierwszym przykładzie, zauważyć, jak liczba nie zmienia:

https://jsfiddle.net/BrianIsSecond/ehkgh2gu/

  1. Teraz, powiedzmy, że $(window) nie jest pojemnikiem, który przewija. Zamiast tego utworzysz element div, który ma "overflow-y: scroll;" zestaw atrybutów. W takim przypadku $('div#offset').offset().top działa zupełnie inaczej niż w poprzednim przykładzie. Zauważysz, że zmienia się podczas przewijania.W przypadku przykładu JSFiddle po prostu zapakowałem wszystko pod div#overflow, który ma ustawiony atrybut overflow-y:scroll;. Zobacz przykład:

https://jsfiddle.net/BrianIsSecond/tcs390h6/ < --- Należy również zauważyć, że przepełnienie div # nie jest 100% wysokie. Zrobiłem 100px mniej niż 100%. Używam tego do zilustrowania łatwego błędu, który omówię w dalszej części.

  1. Jeśli tak jak ja, przykład 2 nie jest tym, czego chciałeś. Najlepszym rozwiązaniem, jakie znalazłem, jest pobranie $('#overflow').scrollTop() i dodanie go do $('#offset').offset().top (tj. var ep = $('#offset').offset().top + $('#overflow').scrollTop()). Zasadniczo, dodając te dwie zmieniające się liczby, "sortują" się wzajemnie, dając dokładną pozycję elementu div#offset ... czy też? Cóż, tutaj ważne jest położenie div#overflow! Musisz, musisz, musi wziąć pod uwagę pozycję przewijanego pojemnika. Aby to zrobić, weź $('#overflow').offset().top i odejmij go od $('#offset').offset().top, zanim dodasz $('#overflow').scrollTop(). To następnie uwzględni pozycję przewijanego pojemnika z okna. Patrz przykład:

https://jsfiddle.net/BrianIsSecond/yzc5ycyg/

Ostatecznie, czego szukasz, jest coś takiego:

var w = $('#overflow'), // overflow-y:scroll; 
    e = $('#offset');  // element 

$('#overflow').scroll(function(){ 
    var wh = w.height(),        // window height 
     sp = w.scrollTop(),       // scroll position 
     ep = (e.offset().top - w.offset().top) + sp; // element position 

    console.log(ep); 
}); 

UPDATE (11.10.17): Utworzyłem funkcja, aby pomóc rozwiązać ten problem. Cieszyć się!

/* 
function: betterOffset 
hint: Allows you to calculate dynamic and static offset whether they are in a div container with overscroll or not. 

      name:   type:    option:   notes: 
@param  s (static)  boolean    required  default: true | set false for dynamic 
@param  e (element)  string or object required 
@param  v (viewer)  string or object optional  If you leave this out, it will use $(window) by default. What I am calling the 'viewer' is the thing that scrolls (i.e. The element with "overflow-y:scroll;" style.). 

@return     numeric 
*/ 
function betterOffset(s, e, v) { 
    // Set Defaults 
     s = (typeof s == 'boolean') ? s : true; 
     e = (typeof e == 'object') ? e : $(e); 
     if (v != undefined) {v = (typeof v == 'object') ? v : $(v);} else {v = null;} 

    // Set Variables 
     var w = $(window),    // window object 
      wp = w.scrollTop(),   // window position 
      eo = e.offset().top;  // element offset 
     if (v) { 
      var vo = v.offset().top, // viewer offset 
       vp = v.scrollTop();  // viewer position 
     } 

    // Calculate 
     if (s) { 
      return (v) ? (eo - vo) + vp : eo; 
     } else { 
      return (v) ? eo - vo : eo - wp; 
     } 
} 
Powiązane problemy