offsetTop против jQuery.offset (). top

82

Я прочитал это offsetLeftи offsetTopне работаю должным образом во всех браузерах. jQuery.offset()должен предоставить абстракцию для этого, чтобы предоставить правильное значение xbrowser.

Я пытаюсь получить координаты места щелчка по элементу относительно левого верхнего угла элемента.

Проблема в том, что jQuery.offset().topфактически дает мне десятичное значение в FFX 3.6 (в IE и Chrome два значения совпадают).

Эта скрипка показывает проблему. Если щелкнуть нижнее изображение, jQuery.offset().topвозвращается 327,5, но offsetTopвозвращается 328.

Я хотел бы думать, что offset()это возвращает правильное значение, и я должен использовать его, потому что он будет работать во всех браузерах. Однако люди явно не могут щелкать десятичные дроби пикселей. Правильный ли способ определить истинное смещение Math.round()смещения, возвращаемого jQuery? Должен ли я использовать offsetTopвместо этого или какой-то другой метод полностью?

Таблетки от взрыва
источник

Ответы:

15

Я думаю, вы правы, говоря, что люди не могут щелкнуть половину пикселей, поэтому лично я бы использовал округленное смещение jQuery ...

ChristopheCVB
источник
4
Смещение jQuery не работает при использовании масштабирования CSS
Младен Джанжетович
77

Об этом говорится в документации по API jQuery.offset() :

Получить текущие координаты первого элемента или установить координаты каждого элемента в наборе согласованных элементов относительно документа .

Вот что говорит MDN Web API.offsetTop :

offsetTop возвращает расстояние текущего элемента относительно вершины узла offsetParent

Вот что в .offset()основном делает jQuery v.1.11 при получении координат:

var box = { top: 0, left: 0 };

// BlackBerry 5, iOS 3 (original iPhone)
if ( typeof elem.getBoundingClientRect !== strundefined ) {
  box = elem.getBoundingClientRect();
}
win = getWindow( doc );
return {
  top: box.top  + ( win.pageYOffset || docElem.scrollTop )  - ( docElem.clientTop  || 0 ),
  left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
};
  • pageYOffset интуитивно говорит сколько прокручивалась страница
  • docElem.scrollTop является резервным вариантом для IE <9 (которые, кстати, не поддерживаются в jQuery 2)
  • docElem.clientTop ширина верхней границы элемента (в данном случае документа)
  • elem.getBoundingClientRect()получает координаты относительно области просмотра документа (см. комментарии). Он может возвращать дробные значения, так что это источник вашей ошибки. Это также может вызвать ошибку в IE <8 при увеличении страницы. Чтобы избежать дробных значений, попробуйте вычислить позицию итеративно

Заключение

  • Если вам нужны координаты относительно родительского узла , используйте element.offsetTop. Добавьте, element.scrollTopесли вы хотите учитывать родительскую прокрутку. (или используйте jQuery .position () если вам эта библиотека)
  • Если вам нужны координаты относительно области просмотра, используйте element.getBoundingClientRect().top. Добавьте, window.pageYOffsetесли хотите учесть прокрутку документа. Вам не нужно вычитать документ, clientTopесли у документа нет границы (обычно это не так), поэтому у вас есть позиция относительно документа.
  • Вычтите, element.clientTopесли вы не рассматриваете границу элемента как часть элемента
Ян Туро
источник
Element.getBoundingClientRect()дает позиции относительно области просмотра , а не документа
Клаус
@Klaus: не могли бы вы объяснить, в чем именно разница?
Ян Туро
2
@ JanTuroň: Разница в том, что это относится к верхней части окна браузера, а не к «истинной вершине» документов. Это означает, что он вернет отрицательные значения, например, если вы прокрутите его сверху за верхнюю часть окна.
Райан Бадур
5

Попробуй это: parseInt(jQuery.offset().top, 10)

Стив Чан
источник
Я бы хотел, чтобы у этого была причина, чтобы я мог проголосовать за тебя
Кик Бутовски
2

Возможно, что это offsetможет быть нецелое число, используя emв качестве единицы измерения относительное font-sizesв% .

Я также предполагаю, что это offsetможет быть не целое число, когда zoomэто не так, 100%но это зависит от того, как браузер обрабатывает масштабирование.

Эмир
источник
2
если масштаб не равен 100%, offset (). top даст вам множество других проблем ... bugs.jquery.com/ticket/8362
commonpike
-1

Вы можете parseInt(jQuery.offset().top)всегда использовать значение Integer (примитив - int) во всех браузерах.

ШанкарСанголи
источник
1
ParseInt () удваивает или обрезает их?
Explosion Pills
Это будет просто целая часть числа, и она будет одинаковой во всех браузерах.
ShankarSangoli
OP заявляет, что в одном браузере он дает 327,5, а в другом - 328. Итак, если вы просто возьмете целую часть (усечение), сам OP является примером того, что он не является одинаковым во всех браузерах. Для этого примера, по крайней мере, необходимо округлить, чтобы получить одинаковое число.
Джимбо Джонни,