Використовуючи jquery, щоб отримати положення елемента відносно вікна перегляду


117

Який правильний спосіб отримати положення елемента на сторінці відносно вікна перегляду (а не документа). jQuery.offsetФункція видалася перспективною:

Отримайте поточні координати першого елемента або встановіть координати кожного елемента у наборі відповідних елементів відносно документа.

Але це відносно документа. Чи існує еквівалентний метод, який повертає зсуви відносно вікна перегляду?


5
ПРИМІТКА: Дивіться відповідь @ Ігоря Г. ...
Карл Сміт

3
Для DA, ви повинні дійсно встановити відповідь Ігоря Г як прийняту, це рятування життя!
Вінсент Дюпрез

Відповіді:


26

Перегляньте плагін Dimensions, зокрема scrollTop()/ scrollLeft(). Інформацію можна знайти на веб-сайті http://api.jquery.com/scrollTop .


8
Я не хотів використовувати інший плагін, але $ (window) .scrollTop () - саме те, що мені потрібно! Дякую!
DA.

16
Плагін розмірів тепер є частиною ядра jQuery. Плагін ViewPort також може бути корисно: appelsiini.net/projects/viewport
StriplingWarrior

287

Найпростіший спосіб визначити розмір і положення елемента - викликати його метод getBoundingClientRect () . Цей метод повертає елементи елементів у координатах вікна перегляду. Він не очікує ніяких аргументів і повертає об'єкт із властивостями зліва, справа, вгорі та внизу . Лівий і верхній властивості дають координати X і Y верхнього лівого кута елемента, а правий і нижній властивості дають координати правого нижнього кута.

element.getBoundingClientRect(); // Get position in viewport coordinates

Підтримується скрізь.


15
Неймовірно, що цей метод додав IE5 ... коли щось добре, це добре!
roy riojas

Спочатку це здалося чудовим, але він не враховує масштаб користувача на мобільному Safari 7.
MyNameIsKo

2
Не підтримується останньою FirefoxgetBoundingClientRect is not a function
user007

2
@ user007 Я підтверджую, що він підтримується останнім firefox.
adriendenat

26
Чудова відповідь, і щоб це було jquery, просто зробіть це так: $('#myElement')[0].getBoundingClientRect().top(або будь-яку іншу позицію)
Гійом Арлуїсон

40

Ось дві функції для отримання висоти сторінки та суми прокрутки (x, y) без використання плагіна розмірів (здутий):

// getPageScroll() by quirksmode.com
function getPageScroll() {
    var xScroll, yScroll;
    if (self.pageYOffset) {
      yScroll = self.pageYOffset;
      xScroll = self.pageXOffset;
    } else if (document.documentElement && document.documentElement.scrollTop) {
      yScroll = document.documentElement.scrollTop;
      xScroll = document.documentElement.scrollLeft;
    } else if (document.body) {// all other Explorers
      yScroll = document.body.scrollTop;
      xScroll = document.body.scrollLeft;
    }
    return new Array(xScroll,yScroll)
}

// Adapted from getPageSize() by quirksmode.com
function getPageHeight() {
    var windowHeight
    if (self.innerHeight) { // all except Explorer
      windowHeight = self.innerHeight;
    } else if (document.documentElement && document.documentElement.clientHeight) {
      windowHeight = document.documentElement.clientHeight;
    } else if (document.body) { // other Explorers
      windowHeight = document.body.clientHeight;
    }
    return windowHeight
}

Це геніально. Дуже корисний.
Джиммі

З цікавості, чому ви використовували в цьому випадку властивість "Я" замість вікна?
dkugappi


23

jQuery.offsetпотрібно поєднувати з scrollTopта scrollLeftяк показано на цій схемі:

прокрутка вікна перегляду та зміщення елементів

Демонстрація:

function getViewportOffset($e) {
  var $window = $(window),
    scrollLeft = $window.scrollLeft(),
    scrollTop = $window.scrollTop(),
    offset = $e.offset(),
    rect1 = { x1: scrollLeft, y1: scrollTop, x2: scrollLeft + $window.width(), y2: scrollTop + $window.height() },
    rect2 = { x1: offset.left, y1: offset.top, x2: offset.left + $e.width(), y2: offset.top + $e.height() };
  return {
    left: offset.left - scrollLeft,
    top: offset.top - scrollTop,
    insideViewport: rect1.x1 < rect2.x2 && rect1.x2 > rect2.x1 && rect1.y1 < rect2.y2 && rect1.y2 > rect2.y1
  };
}
$(window).on("load scroll resize", function() {
  var viewportOffset = getViewportOffset($("#element"));
  $("#log").text("left: " + viewportOffset.left + ", top: " + viewportOffset.top + ", insideViewport: " + viewportOffset.insideViewport);
});
body { margin: 0; padding: 0; width: 1600px; height: 2048px; background-color: #CCCCCC; }
#element { width: 384px; height: 384px; margin-top: 1088px; margin-left: 768px; background-color: #99CCFF; }
#log { position: fixed; left: 0; top: 0; font: medium monospace; background-color: #EEE8AA; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

<!-- scroll right and bottom to locate the blue square -->
<div id="element"></div>
<div id="log"></div>


2
це спрацювало для мене чудово, але я використовував це, щоб визначити, чи підказка не виходить за межі, тому я змінив, щоб включити нижній і правий значення: jsfiddle.net/EY6Rk/21
Йорданія,

Це абсолютно, у будь-якому випадку, правильна відповідь. Усі інші мають проблеми залежно від конфігурації дельти миші / прокрутки, браузерів, місця розташування тощо
Педро Феррейра

2

Ось функція, яка обчислює поточне положення елемента в області перегляду:

/**
 * Calculates the position of a given element within the viewport
 *
 * @param {string} obj jQuery object of the dom element to be monitored
 * @return {array} An array containing both X and Y positions as a number
 * ranging from 0 (under/right of viewport) to 1 (above/left of viewport)
 */
function visibility(obj) {
    var winw = jQuery(window).width(), winh = jQuery(window).height(),
        elw = obj.width(), elh = obj.height(),
        o = obj[0].getBoundingClientRect(),
        x1 = o.left - winw, x2 = o.left + elw,
        y1 = o.top - winh, y2 = o.top + elh;

    return [
        Math.max(0, Math.min((0 - x1) / (x2 - x1), 1)),
        Math.max(0, Math.min((0 - y1) / (y2 - y1), 1))
    ];
}

Повернені значення обчислюються так:

Використання:

visibility($('#example'));  // returns [0.3742887830933581, 0.6103752759381899]

Демонстрація:

function visibility(obj) {var winw = jQuery(window).width(),winh = jQuery(window).height(),elw = obj.width(),
    elh = obj.height(), o = obj[0].getBoundingClientRect(),x1 = o.left - winw, x2 = o.left + elw, y1 = o.top - winh, y2 = o.top + elh; return [Math.max(0, Math.min((0 - x1) / (x2 - x1), 1)),Math.max(0, Math.min((0 - y1) / (y2 - y1), 1))];
}
setInterval(function() {
  res = visibility($('#block'));
  $('#x').text(Math.round(res[0] * 100) + '%');
  $('#y').text(Math.round(res[1] * 100) + '%');
}, 100);
#block { width: 100px; height: 100px; border: 1px solid red; background: yellow; top: 50%; left: 50%; position: relative;
} #container { background: #EFF0F1; height: 950px; width: 1800px; margin-top: -40%; margin-left: -40%; overflow: scroll; position: relative;
} #res { position: fixed; top: 0; z-index: 2; font-family: Verdana; background: #c0c0c0; line-height: .1em; padding: 0 .5em; font-size: 12px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="res">
  <p>X: <span id="x"></span></p>
  <p>Y: <span id="y"></span></p>
</div>
<div id="container"><div id="block"></div></div>


0

Я виявив, що відповідь cballou більше не працював у Firefox станом на січень 2014 року. Зокрема, if (self.pageYOffset)не спрацьовувало, якщо клієнт прокручував правильно, але не вниз - тому що 0це номер фальси. Це на деякий час не виявлено, оскільки Firefox підтримує document.body.scrollLeft/ Top, але це більше не працює для мене (на Firefox 26.0).

Ось моє модифіковане рішення:

var getPageScroll = function(document_el, window_el) {
  var xScroll = 0, yScroll = 0;
  if (window_el.pageYOffset !== undefined) {
    yScroll = window_el.pageYOffset;
    xScroll = window_el.pageXOffset;
  } else if (document_el.documentElement !== undefined && document_el.documentElement.scrollTop) {
    yScroll = document_el.documentElement.scrollTop;
    xScroll = document_el.documentElement.scrollLeft;
  } else if (document_el.body !== undefined) {// all other Explorers
    yScroll = document_el.body.scrollTop;
    xScroll = document_el.body.scrollLeft;
  }
  return [xScroll,yScroll];
};

Тестували та працювали в FF26, Chrome 31, IE11. Майже напевно працює на старих версіях усіх.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.