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 ...


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ň: Разница в том, что это относится к верхней части окна браузера, а не к «истинной вершине» документов. Это означает, что он вернет отрицательные значения, например, если вы прокрутите его сверху за верхнюю часть окна.
Райан Бадур


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 является примером того, что он не является одинаковым во всех браузерах. Для этого примера, по крайней мере, необходимо округлить, чтобы получить одинаковое число.
Джимбо Джонни,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.