Подтвердить что ты не робот

Изменение значений смещения jquery путем прокрутки страницы

var offset = $(selector).offset();

Значения переменной смещения изменяются, если мы прокручиваем страницу вверх и вниз, я хочу точные и фиксированные значения смещения, сохраняя позицию "селектора" по умолчанию (статический). Как я могу это сделать?

4b9b3361

Ответ 1

Вы всегда можете рассчитать смещение, факторинг в позиции прокрутки:

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

Ответ 2

Просто хотел добавить свой ответ здесь, после того, как у вас были такие же проблемы:

После получения описанного выше поведения Я посмотрел документацию jQuery и обнаружил, что

jQuery не поддерживает получение смещенных координат элементов скрытых или учет границ, полей или отступов, установленных в элементе body.

Элемент, который я пытался получить смещение, на самом деле был установлен на display:none;, что дало мне ложное смещение, которое изменилось при прокрутке (даже если элемент не двигался).

Поэтому убедитесь, что вы не пытаетесь получить смещение скрытого элемента! надеюсь, это поможет кому-то:)

Ответ 3

Еще одна потенциальная причина - если ваш <body> имеет CSS, который устанавливает overflow-x: hidden; - полностью разрушает метод jQuery offset().

В этом случае $(window).scrollTop() всегда равно 0, поэтому принятый ответ не работает.

Ответ 4

У меня была очень похожая проблема с исходным вопросом. Смещение непросто. Надеюсь, это поможет решить ваши проблемы, как и мои. У меня есть 3 JSFiddles, чтобы продемонстрировать.

  • Если вы используете offset().top вашего элемента div из окна, вы всегда получите статическое число (т.е. если $(window) - это свиток, и у вас есть div внутри окна с offset().top применяется div всегда будет иметь статическое число). Это смещение - точное количество пикселей, которое элемент существует из верхней части $(window), независимо от того, насколько далеко вы прокручиваете его. Для каждого из моих JSFiddles я посмотрю, как далеко от объекта $('div#offset') находится верхняя часть его прокручиваемого контейнера. В этом первом примере обратите внимание на то, как число не изменяется:

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

  1. Теперь скажем, что $(window) - это не тот контейнер, который прокручивается. Вместо этого вы создаете div, у которого есть "переполнение-y: прокрутка"; набор атрибутов. В этом случае $('div#offset').offset().top действует совсем иначе, чем предыдущий пример. Вы заметите, что это изменится при прокрутке. Для моего примера JSFiddle я просто завернул все в div#overflow, у которого установлен атрибут overflow-y:scroll;. Пример:

https://jsfiddle.net/BrianIsSecond/tcs390h6/ < --- Обратите внимание, что переполнение div # не на 100%. Я сделал 100px меньше 100%. Я использую это, чтобы проиллюстрировать легкую ошибку, о которой я расскажу ниже.

  1. Если ваш, как я, пример 2, вы не хотите. Лучшее решение, которое я нашел, - захватить $('#overflow').scrollTop() и добавить его в $('#offset').offset().top (т.е. var ep = $('#offset').offset().top + $('#overflow').scrollTop()). В принципе, добавляя эти два изменяющихся числа вместе, они "сортируют", отменяют друг друга, давая вам точное положение элемента div#offset... или они? Ну, вот где положение div#overflow важно! Вы должны, должны, принять во внимание положение прокручиваемого контейнера. Чтобы сделать это, возьмите $('#overflow').offset().top и вычтите его из $('#offset').offset().top, прежде чем добавить $('#overflow').scrollTop(). Затем это будет зависеть от положения прокручиваемого контейнера из окна. Пример:

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

В конечном счете то, что вы ищете, выглядит примерно так:

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 (10/11/17): Я создал функцию, помогающую решить эту проблему. Наслаждайтесь!

/*
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;
        }
}

Ответ 5

В 2015 году "правильный" ответ больше не должен использоваться - смещение было изменено. Любой код, который использовал вышеупомянутое решение, больше не будет работать должным образом.

Решение: обновите jquery до более новой версии (работает в 1.11.3). Или... измените .offset вызов вместо использования .position.