OffsetTop vs. jQuery.offset(). top

Я прочитал, что 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 или какой-то другой метод полностью?

Ответ 1

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

Ответ 2

Вот что JQuery API Doc говорит о .offset():

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

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

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

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

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 если вы не рассматриваете границу элемента как часть элемента

Ответ 3

Попробуйте следующее: parseInt(jQuery.offset().top, 10)

Ответ 4

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

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

Ответ 5

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