JQuery получить расположение элемента относительно окна

168

Учитывая HTML DOM ID, как получить позицию элемента относительно окна в JavaScript / JQuery? Это не то же самое, что относительно документа и родительского смещения, так как элемент может быть внутри iframe или некоторых других элементов. Мне нужно получить местоположение на экране прямоугольника элемента (как в положении и измерении), так как он отображается в данный момент. Отрицательные значения допустимы, если элемент в данный момент находится за пределами экрана (был отключен).

Это для приложения iPad (WebKit / WebView). Всякий раз, когда пользователь нажимает на специальную ссылку в UIWebView, я должен открыть всплывающее окно, которое отображает дополнительную информацию о ссылке. Всплывающее представление должно отображать стрелку, указывающую назад на ту часть экрана, которая его вызывает.

Adib
источник

Ответы:

264

Первоначально, захватите положение .offset элемента и вычислите его относительное положение относительно окна.

Обратитесь :
1. смещение
2. прокрутка
3. scrollTop

Вы можете попробовать это на этой скрипке

Следующие несколько строк кода объясняют, как это можно решить

когда выполняется событие .scroll , мы вычисляем относительное положение элемента относительно объекта окна

$(window).scroll(function () {
    console.log(eTop - $(window).scrollTop());
});

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

фрагмент кода


function log(txt) {
  $("#log").html("location : <b>" + txt + "</b> px")
}

$(function() {
  var eTop = $('#element').offset().top; //get the offset top of the element
  log(eTop - $(window).scrollTop()); //position of the ele w.r.t window

  $(window).scroll(function() { //when window is scrolled
    log(eTop - $(window).scrollTop());
  });
});
#element {
  margin: 140px;
  text-align: center;
  padding: 5px;
  width: 200px;
  height: 200px;
  border: 1px solid #0099f9;
  border-radius: 3px;
  background: #444;
  color: #0099d9;
  opacity: 0.6;
}
#log {
  position: fixed;
  top: 40px;
  left: 40px;
  color: #333;
}
#scroll {
  position: fixed;
  bottom: 10px;
  right: 10px;
  border: 1px solid #000;
  border-radius: 2px;
  padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="log"></div>

<div id="element">Hello
  <hr>World</div>
<div id="scroll">Scroll Down</div>

jterry
источник
1
Спасибо за сценарий. Кажется, это работает на рабочем столе, но не работает на iPad. Похоже, что $ (window) .scrollTop () и $ (window) .scrollLeft () не обновляются в iPad. Вы можете попробовать мою версию через jsbin.com/ogiwu4/5
2010 г.
2
Они не обновляются на iPad, потому что само окно не прокручивается - пользователь прокручивает внутри окна. В любом случае, это относится к основному веб-сайту, не уверенному в том, что он предназначен для мобильных устройств, возможно, там есть больше вариантов.
eselk
Это должно произойти сбой, когда элемент находится внутри другого прокручиваемого элемента, т.е. грамм. <div>, Вы рассматриваете только прокрутку документа, но не прокрутку другого элемента.
ygoe
71

Попробуйте ограничительную рамку. Это просто:

var leftPos  = $("#element")[0].getBoundingClientRect().left   + $(window)['scrollLeft']();
var rightPos = $("#element")[0].getBoundingClientRect().right  + $(window)['scrollLeft']();
var topPos   = $("#element")[0].getBoundingClientRect().top    + $(window)['scrollTop']();
var bottomPos= $("#element")[0].getBoundingClientRect().bottom + $(window)['scrollTop']();
prograhammer
источник
7
getBoundingClientRect () является ответом на эту проблему. Спасибо, програхаммер.
Влад Лего
1
это сработало хорошо. Мне просто нужно было включить код для исправления прокрутки, в дополнение к вашим scrollLetf и scrollTop: topPos = topPos - $ (window) .scrollTop (); leftPos = leftPos - $ (окно) .scrollLeft (); rightPos = rightPos - $ (window) .scrollTop (); bottomPos = bottomPos - $ (окно) .scrollLeft ();
Цезарь
1
день, когда люди будут учиться оборачивать вещи приятным полезным методом
ммм
@Noldorin Мне очень нравится поддержка IE / Edge: caniuse.com/#feat=getboundingclientrect
prograhammer
1
@prograhammer Мой плохой, ты прав. Я прочитал это на каком-то сайте и взял его слово за чистую монету ... оказалось, что это было неправильно (или, по крайней мере, не работает на старых IE).
Нолдорин
6
function getWindowRelativeOffset(parentWindow, elem) {
        var offset = {
            left : 0,
            top : 0
        };
        // relative to the target field's document
        offset.left = elem.getBoundingClientRect().left;
        offset.top = elem.getBoundingClientRect().top;
        // now we will calculate according to the current document, this current
        // document might be same as the document of target field or it may be
        // parent of the document of the target field
        var childWindow = elem.document.frames.window;
        while (childWindow != parentWindow) {
            offset.left = offset.left + childWindow.frameElement.getBoundingClientRect().left;
            offset.top = offset.top + childWindow.frameElement.getBoundingClientRect().top;
            childWindow = childWindow.parent;
        }
        return offset;
    };

Вы можете назвать это так

getWindowRelativeOffset(top, inputElement);

Я ориентируюсь на IE только в соответствии с моим требованием, но подобное можно сделать для других браузеров

Имран Ансари
источник
4

Это больше похоже на то, что вы хотите всплывающую подсказку для выбранной ссылки. Существует множество подсказок jQuery, попробуйте jQuery qTip . Он имеет много опций и легко меняет стили.

В противном случае, если вы хотите сделать это самостоятельно, вы можете использовать jQuery .position(). Более подробная информация о .position()на http://api.jquery.com/position/

$("#element").position(); вернет текущую позицию элемента относительно смещения родителя.

Также есть jQuery .offset (); который вернет позицию относительно документа.

jhanifen
источник
2
На самом деле это не всплывающая подсказка, но чтобы открыть собственный виджет пользовательского интерфейса для добавления аннотаций.
2010 г.
3

TL; DR

headroom_by_jQuery = $('#id').offset().top - $(window).scrollTop();

headroom_by_DOM = $('#id')[0].getBoundingClientRect().top;   // if no iframe

.getBoundingClientRect () представляется универсальным . .offset () и .scrollTop () поддерживаются начиная с jQuery 1.2. Спасибо @ user372551 и @prograhammer. Чтобы использовать DOM в iframe, смотрите решение @ ImranAnsari .

Боб Стейн
источник
1
    function trbl(e, relative) {
            var r = $(e).get(0).getBoundingClientRect(); relative = $(relative);

            return {
                    t : r.top    + relative['scrollTop'] (),
                    r : r.right  + relative['scrollLeft'](),
                    b : r.bottom + relative['scrollTop'] (),
                    l : r.left   + relative['scrollLeft']() 

            }
    }

    // Example
    trbl(e, window);
ммм
источник
1

Попробуйте это, чтобы получить расположение элемента относительно окна.

        $("button").click(function(){
            var offset = $("#simplebox").offset();
            alert("Current position of the box is: (left: " + offset.left + ", top: " + offset.top + ")");
        });
    #simplebox{
        width:150px;
        height:100px;
        background: #FBBC09;
        margin: 150px 100px;
    }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button">Get Box Position</button>
    <p><strong>Note:</strong> Play with the value of margin property to see how the jQuery offest() method works.</p>
    <div id="simplebox"></div>

Узнать больше @ Получить позицию элемента относительно документа с помощью jQuery

Кетан Савалия
источник