Как получить местоположение элемента после его нажатия? [Дубликат]

Это работает для ввода, поступающего из текстового поля

str.replace(new RegExp('\r?\n','g'), '<br />');
1096
задан Greg 10 August 2013 в 11:30
поделиться

24 ответа

Для эффективного получения позиции относительно страницы и без использования рекурсивной функции: (также включает IE)

var element = document.getElementById('elementId'); //replace elementId with your element's Id.
var rect = element.getBoundingClientRect();
var elementLeft,elementTop; //x and y
var scrollTop = document.documentElement.scrollTop?
                document.documentElement.scrollTop:document.body.scrollTop;
var scrollLeft = document.documentElement.scrollLeft?                   
                 document.documentElement.scrollLeft:document.body.scrollLeft;
elementTop = rect.top+scrollTop;
elementLeft = rect.left+scrollLeft;
21
ответ дан Abdul Rahim Haddad 21 August 2018 в 12:00
поделиться
  • 1
    Включение всех важных scrollTop / scrollLeft делает этот ответ немного более правильным. – scunliffe 6 December 2014 в 23:24

Это сработало для меня (изменено с наивысшего проголосовавшего ответа):

function getOffset(el) {
  const rect = el.getBoundingClientRect();
  return {
    left: rect.left + window.scrollX,
    top: rect.top + window.scrollY
  };
}

Используя это, мы можем вызвать

getOffset(element).left

или

getOffset(element).top
145
ответ дан Adam Grant 21 August 2018 в 12:00
поделиться
  • 1
    Ницца и просто. Почему больше людей не нравится это решение? – Scott Biggs 2 April 2015 в 21:06
  • 2
    Только это решение работает для меня, когда элемент помещается в div, в центре которого используется css top:50%, left:50%; transform:translate(-50%, -50%); ... отлично. Согласитесь с вопросом @ScottBiggs. Логично искать простоту. – nelek 3 September 2015 в 20:57
  • 3
    возможно, это не победитель, потому что он так же, как и решение Andy E, но не работает в старых браузерах & lt; IE9 – niltoid 10 June 2016 в 21:36
  • 4
    Очень полезно!! Спасибо друг. – Omar AlMA3lOl 30 July 2016 в 17:20
  • 5
    Это лучшее решение здесь. – RubyFanatic 8 September 2016 в 00:20
  • 6
  • 7
  • 8

Как о чем-то подобном, передавая идентификатор элемента, и он вернет левый или верхний, мы также можем их комбинировать:

1) найти слева

function findLeft(element) {
  var rec = document.getElementById(element).getBoundingClientRect();
  return rec.left + window.scrollX;
} //call it like findLeft('#header');

2) найти верх

function findTop(element) {
  var rec = document.getElementById(element).getBoundingClientRect();
  return rec.top + window.scrollY;
} //call it like findTop('#header');

или 3) найти слева и сверху вместе

function findTopLeft(element) {
  var rec = document.getElementById(element).getBoundingClientRect();
  return {top: rec.top + window.scrollY, left: rec.left + window.scrollX};
} //call it like findTopLeft('#header');
18
ответ дан Alireza 21 August 2018 в 12:00
поделиться

Элементы HTML в большинстве браузеров будут иметь: -

offsetLeft
offsetTop

Они определяют положение элемента относительно его ближайшего родителя с макетом. Этот родительский элемент часто можно получить с помощью свойства offsetParent.

IE и FF3 имеют

clientLeft
clientTop

Эти свойства менее распространены, они определяют позицию элементов с клиентской областью его родителей (дополненные область является частью клиентской области, но граница и маржа не являются).

26
ответ дан AnthonyWJones 21 August 2018 в 12:00
поделиться

Так как разные браузеры - это визуализация границы, отступов, полей и т. д. по-разному. Я написал небольшую функцию для получения верхней и левой позиций определенного элемента в каждом корневом элементе, который вы хотите в точном измерении:

function getTop(root, offset) {
    var rootRect = root.getBoundingClientRect();
    var offsetRect = offset.getBoundingClientRect();
    return offsetRect.top - rootRect.top;
}

Для получения левой позиции вы должны вернуться:

    return offsetRect.left - rootRect.left;
0
ответ дан arrowd 21 August 2018 в 12:00
поделиться

Я сделал это так, чтобы он был кросс-совместим со старыми браузерами.

// For really old browser's or incompatible ones
    function getOffsetSum(elem) {
        var top = 0,
            left = 0,
            bottom = 0,
            right = 0

         var width = elem.offsetWidth;
         var height = elem.offsetHeight;

        while (elem) {
            top += elem.offsetTop;
            left += elem.offsetLeft;
            elem = elem.offsetParent;
        }

         right = left + width;
         bottom = top + height;

        return {
            top: top,
            left: left,
            bottom: bottom,
            right: right,
        }
    }

    function getOffsetRect(elem) {
        var box = elem.getBoundingClientRect();

        var body = document.body;
        var docElem = document.documentElement;

        var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop;
        var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft;

        var clientTop = docElem.clientTop;
        var clientLeft = docElem.clientLeft;


        var top = box.top + scrollTop - clientTop;
        var left = box.left + scrollLeft - clientLeft;
        var bottom = top + (box.bottom - box.top);
        var right = left + (box.right - box.left);

        return {
            top: Math.round(top),
            left: Math.round(left),
            bottom: Math.round(bottom),
            right: Math.round(right),
        }
    }

    function getOffset(elem) {
        if (elem) {
            if (elem.getBoundingClientRect) {
                return getOffsetRect(elem);
            } else { // old browser
                return getOffsetSum(elem);
            }
        } else
            return null;
    }

Подробнее о координатах в JavaScript здесь: http://javascript.info/tutorial/coordinates

4
ответ дан Bojan Kseneman 21 August 2018 в 12:00
поделиться

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

14
ответ дан cosbor11 21 August 2018 в 12:00
поделиться
  • 1
    По некоторым причинам он не дает те же результаты в IE по сравнению с другими браузерами. Я думаю, что в IE он дает позицию относительно окна, поэтому, если вы прокручиваете, вы будете получать разные результаты в IE по сравнению с другими – Abdul Rahim Haddad 10 August 2013 в 17:19
  • 2
    offset () путается масштабированием, по крайней мере, в Android Chrome, поэтому бесполезно. stackoverflow.com/a/11396681/1691517 показывает масштабируемость. – Timo Kähkönen 31 May 2015 в 18:45

Библиотеки идут на несколько длин, чтобы получить точные смещения для элемента. вот простая функция, которая выполняет работу в любых обстоятельствах, которые я пробовал.

function getOffset( el ) {
    var _x = 0;
    var _y = 0;
    while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {
        _x += el.offsetLeft - el.scrollLeft;
        _y += el.offsetTop - el.scrollTop;
        el = el.offsetParent;
    }
    return { top: _y, left: _x };
}
var x = getOffset( document.getElementById('yourElId') ).left; 
258
ответ дан Da-Jin 21 August 2018 в 12:00
поделиться
  • 1
    change: el = el.parentNode to: el = el.offsetParent; и, похоже, теперь он работает для вложенных iframe ... Я думаю, это то, что вы намеревались? – Adam 29 July 2009 в 21:19
  • 2
    Это решение является неполным. Попробуйте положить толстую границу на div и несколько раз вложить ее в гнездо. В любой версии Firefox (2-5) она будет отключена шириной (границами) границы (даже в режиме соблюдения стандартов). – ck_ 5 August 2011 в 06:21
  • 3
    нет ли более чистого способа сделать это, как функция el.totalOffsetLeft и totalOffsetTop? Конечно, у jQuery есть этот вариант, но стыдно, что для этого нет официального метода, нужно ли ждать DOM4? Я создаю приложение холста HTML5, поэтому я считаю, что лучшим решением было бы вставить элемент canvas в iframe, чтобы я мог получить реальные координаты с clientX и clientY, когда мы нажимаем на элемент. – baptx 30 May 2012 в 18:04
  • 4
    Итак, @Adam и meouw, вы говорите, что первый блок кода ошибочен? Тогда почему бы вообще не удалить это? (На протяжении многих лет этот вопрос видел довольно много зрителей, возможно, было бы неплохо удалить вещи, если они ошибаются?) – Arjan 12 August 2012 в 00:35
  • 5
    Это не работает для преобразованных элементов. – Alex 26 August 2014 в 22:44

Просто подумал, что я тоже выброшу это. Я не смог проверить его в старых браузерах, но он работает в последней версии 3.:)

Element.prototype.getOffsetTop = function() {
    return ( this.parentElement )? this.offsetTop + this.parentElement.getOffsetTop(): this.offsetTop;
};
Element.prototype.getOffsetLeft = function() {
    return ( this.parentElement )? this.offsetLeft + this.parentElement.getOffsetLeft(): this.offsetLeft;
};
Element.prototype.getOffset = function() {
    return {'left':this.getOffsetLeft(),'top':this.getOffsetTop()};
};
1
ответ дан Duncan 21 August 2018 в 12:00
поделиться

Если на странице есть - по крайней мере, любой «DIV», функция, заданная meouw, выдает значение «Y» за пределы текущей страницы. Чтобы найти точную позицию, вам нужно обрабатывать как offsetParent, так и parentNode.

Попробуйте приведенный ниже код (он проверяется на FF2):


var getAbsPosition = function(el){
    var el2 = el;
    var curtop = 0;
    var curleft = 0;
    if (document.getElementById || document.all) {
        do  {
            curleft += el.offsetLeft-el.scrollLeft;
            curtop += el.offsetTop-el.scrollTop;
            el = el.offsetParent;
            el2 = el2.parentNode;
            while (el2 != el) {
                curleft -= el2.scrollLeft;
                curtop -= el2.scrollTop;
                el2 = el2.parentNode;
            }
        } while (el.offsetParent);

    } else if (document.layers) {
        curtop += el.y;
        curleft += el.x;
    }
    return [curtop, curleft];
};

29
ответ дан hev1 21 August 2018 в 12:00
поделиться
  • 1
    как и в других решениях даже с FF 24.4, вышеуказанный код не работает, если границы границ существуют как часть расположения позиционирования. – rob 12 May 2014 в 21:46
  • 2
    Спасибо за эту функцию. Он работал на то, что мне нужно. – HotFudgeSunday 25 March 2015 в 15:37
  • 3
    Ты спасатель жизни. Я работаю над некоторыми довольно глубокими ошибками GWT прямо сейчас, и бросать это в метод JSNI решает все мои проблемы! – Will Byrne 10 June 2015 в 21:27

Если вы используете jQuery, это может быть простое решение:

<script>
  var el = $("#element");
  var position = el.position();
  console.log( "left: " + position.left + ", top: " + position.top );
</script>
7
ответ дан iMad 21 August 2018 в 12:00
поделиться

Я принял ответ @ meouw, добавленный в clientLeft, который разрешает границу, а затем создал три версии:

getAbsoluteOffsetFromBody - похоже на @ meouw's, это получает абсолютное положение относительно тела или элемент html документа (в зависимости от режима quirks)

getAbsoluteOffsetFromGivenElement - возвращает абсолютную позицию относительно данного элемента (relativeEl). Обратите внимание, что данный элемент должен содержать элемент el, иначе он будет вести себя так же, как getAbsoluteOffsetFromBody. Это полезно, если у вас есть два элемента, содержащиеся в другом (известном) элементе (необязательно несколько узлов вверх по дереву узлов) и хотите сделать их одинаковыми.

getAbsoluteOffsetFromRelative - возвращает абсолютное положение относительно первого родительский элемент с положением: относительный. Это похоже на getAbsoluteOffsetFromGivenElement по той же причине, но будет идти только до первого элемента соответствия.

getAbsoluteOffsetFromBody = function( el )
{   // finds the offset of el from the body or html element
    var _x = 0;
    var _y = 0;
    while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) )
    {
        _x += el.offsetLeft - el.scrollLeft + el.clientLeft;
        _y += el.offsetTop - el.scrollTop + el.clientTop;
        el = el.offsetParent;
    }
    return { top: _y, left: _x };
}

getAbsoluteOffsetFromGivenElement = function( el, relativeEl )
{   // finds the offset of el from relativeEl
    var _x = 0;
    var _y = 0;
    while( el && el != relativeEl && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) )
    {
        _x += el.offsetLeft - el.scrollLeft + el.clientLeft;
        _y += el.offsetTop - el.scrollTop + el.clientTop;
        el = el.offsetParent;
    }
    return { top: _y, left: _x };
}

getAbsoluteOffsetFromRelative = function( el )
{   // finds the offset of el from the first parent with position: relative
    var _x = 0;
    var _y = 0;
    while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) )
    {
        _x += el.offsetLeft - el.scrollLeft + el.clientLeft;
        _y += el.offsetTop - el.scrollTop + el.clientTop;
        el = el.offsetParent;
        if (el != null)
        {
            if (getComputedStyle !== 'undefined')
                valString = getComputedStyle(el, null).getPropertyValue('position');
            else
                valString = el.currentStyle['position'];
            if (valString === "relative")
                el = null;
        }
    }
    return { top: _y, left: _x };
}

Если у вас по-прежнему возникают проблемы, особенно связанные с прокруткой, вы можете попробовать посмотреть http://www.greywyvern.com/?post=331 - Я заметил в getStyle хотя бы один кусок сомнительного кода, который должен быть в порядке, если браузеры ведут себя, но не тестировали остальное вообще.

9
ответ дан James Carlyle-Clarke 21 August 2018 в 12:00
поделиться
  • 1
    Интересно ... но на Edge getAbsoluteOffsetFromBody (element) .top возвращает другое значение при прокрутке, в Chrome он остается неизменным, когда я прокручиваю. Кажется, Edge настраивается с помощью положения прокрутки. Когда элемент прокручивается вне поля зрения, я получаю отрицательное значение. – Norman 13 January 2018 в 17:13
  • 2
    getAbsoluteOffsetFromRelative сделал мой день, мне пришлось воспроизвести всплывающую подсказку без Javascript bootstrap, это очень помогло мне. – Nolyurn 13 August 2018 в 15:52

Самый чистый подход, который я нашел, - это упрощенная версия метода, используемого jQuery offset. Подобно некоторым другим ответам, он начинается с getBoundingClientRect; он затем использует window и documentElement для настройки положения прокрутки, а также таких вещей, как маржа на body (часто по умолчанию).

var rect = el.getBoundingClientRect();
var docEl = document.documentElement;

var rectTop = rect.top + window.pageYOffset - docEl.clientTop;
var rectLeft = rect.left + window.pageXOffset - docEl.clientLeft;

var els = document.getElementsByTagName("div");
var docEl = document.documentElement;

for (var i = 0; i < els.length; i++) {

  var rect = els[i].getBoundingClientRect();

  var rectTop = rect.top + window.pageYOffset - docEl.clientTop;
  var rectLeft = rect.left + window.pageXOffset - docEl.clientLeft;

  els[i].innerHTML = "<b>" + rectLeft + ", " + rectTop + "</b>";
}
div {
  width: 100px;
  height: 100px;
  background-color: red;
  border: 1px solid black;
}
#rel {
  position: relative;
  left: 10px;
  top: 10px;
}
#abs {
  position: absolute;
  top: 250px;
  left: 250px;
}
<div id="rel"></div>
<div id="abs"></div>
<div></div>

5
ответ дан James Montagne 21 August 2018 в 12:00
поделиться

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

например

Относительное положение, абсолютное положение, абсолютное позиция без заполнения, с дополнением ...

Продолжается, давайте просто скажем, что вы можете с ним многое сделать.

Кроме того, бонус использования jQuery - это легкий файл размер и простоту использования, вы не вернетесь к JavaScript без него.

8
ответ дан Jesper Rønn-Jensen 21 August 2018 в 12:00
поделиться

Правильный подход заключается в использовании element.getBoundingClientRect() :

var rect = element.getBoundingClientRect();
console.log(rect.top, rect.right, rect.bottom, rect.left);

Internet Explorer поддерживал это, поскольку до тех пор, пока вы, вероятно, будете заботиться и окончательно стандартизированы в Представления CSSOM . Все другие браузеры уже давно использовали .

Некоторые браузеры также возвращают свойства высоты и ширины, хотя это нестандартно. Если вы обеспокоены более старой совместимостью с браузером, проверьте изменения этого ответа для оптимизированной унизительной реализации.

Значения, возвращаемые element.getBoundingClientRect(), относятся к окну просмотра. Если вам нужно это относительно другого элемента, просто вычтите один прямоугольник из другого:

var bodyRect = document.body.getBoundingClientRect(),
    elemRect = element.getBoundingClientRect(),
    offset   = elemRect.top - bodyRect.top;

alert('Element is ' + offset + ' vertical pixels from <body>');
1317
ответ дан jwhitlock 21 August 2018 в 12:00
поделиться
  • 1
    A очень интересная статья о координатах JS . Эта статья упоминается нигде на SO, она должна ... – Ring Ø 19 February 2014 в 12:55
  • 2
    Не работает ... это 8 пикселей из вертикали и горизонтали, из-за края 8px в теле. Решение Meouw отлично работает. Если хотите, у меня есть небольшой тест, чтобы продемонстрировать проблему. – CpnCrunch 1 July 2014 в 03:30
  • 3
    На самом деле, я думаю, это зависит от того, что вы на самом деле хотите получить. Вопрос немного неоднозначен. Ваш ответ правильный, если вы просто хотите, чтобы координаты относились к окну просмотра или относились к элементу body, но это не поможет вам в случае, когда вы хотите абсолютное положение элемента (что я себе представляю, чего хочет большинство людей) , Ответ meouw не дает вам этого, если вы не удалите биты '-scrollLeft' и '-scrollTop'. – CpnCrunch 3 July 2014 в 18:58
  • 4
    @CpnCrunch: Я понимаю, что вы имеете в виду сейчас; Я не понимал, что речь идет о последней части моего ответа. Когда тело имеет запас, его ограничивающий прямоугольник будет смещен на это количество пикселей на каждой соответствующей стороне. В этом случае вам также нужно будет вычесть вычисленный стиль поля из координат тела. Стоит отметить, что CSS сбрасывает удаление маржи с <body>. – Andy E 4 July 2014 в 16:14
  • 5
    Это отвечает на решение elemRect.top - bodyRect.top, и, похоже, elemRect.left - bodyRect.left, к счастью, устойчиво к увеличению. Смещение jQuery () дает разные результаты, когда окно масштабируется в Android Chrome. jQuery сдается относительно offset(): размеры могут быть неправильными, когда страница масштабируется пользователем; браузеры не выставляют API для обнаружения этого условия. Используя это решение для ответов, вам не нужен API для определения условия масштабирования. – Timo Kähkönen 31 May 2015 в 17:12

Вы можете добавить два свойства к Element.prototype, чтобы получить верхнюю / левую часть любого элемента.

Object.defineProperty( Element.prototype, 'documentOffsetTop', {
    get: function () { 
        return this.offsetTop + ( this.offsetParent ? this.offsetParent.documentOffsetTop : 0 );
    }
} );

Object.defineProperty( Element.prototype, 'documentOffsetLeft', {
    get: function () { 
        return this.offsetLeft + ( this.offsetParent ? this.offsetParent.documentOffsetLeft : 0 );
    }
} );

Это называется так:

var x = document.getElementById( 'myDiv' ).documentOffsetLeft;

Вот demo сравнивая результаты с jQuery offset().top и .left: http://jsfiddle.net/ThinkingStiff/3G7EZ/

28
ответ дан K-Gun 21 August 2018 в 12:00
поделиться
  • 1
    Element.prototype обычно считается плохая идея . Это приводит к очень тяжело поддерживать код. Кроме того, этот код не учитывает прокрутку. – Jared Forsyth 22 June 2015 в 21:58

После долгих исследований и тестирования это, похоже, работает

function getPosition(e) {
    var isNotFirefox = (navigator.userAgent.toLowerCase().indexOf('firefox') == -1);
    var x = 0, y = 0;
    while (e) {
        x += e.offsetLeft - e.scrollLeft + (isNotFirefox ? e.clientLeft : 0);
        y += e.offsetTop - e.scrollTop + (isNotFirefox ? e.clientTop : 0);
        e = e.offsetParent;
    }
    return { x: x + window.scrollX, y: y + window.scrollY };
}

см. http://jsbin.com/xuvovalifo/edit?html,js,output

1
ответ дан kernowcode 21 August 2018 в 12:00
поделиться

Разница между малыми и маленькими

function getPosition( el ) {
    var x = 0;
    var y = 0;
    while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {
    x += el.offsetLeft - el.scrollLeft;
    y += el.offsetTop - el.scrollTop;
    el = el.offsetParent;
    }
    return { top: y, left: x };
}

Посмотрите пример координат: http://javascript.info/tutorial/coordinates

7
ответ дан KingRider 21 August 2018 в 12:00
поделиться
  • 1
    Это, к сожалению, не работает для всех элементов, которые можно найти в современном HTML-документе. Например, встроенные элементы <svg> не имеют свойств offsetLeft, offsetTop и offsetParent. – Jonathan Eunice 19 October 2016 в 09:39
  • 2
    Его просто DIV или IMG, а не SVG. Просмотр & quot; Посмотрите пример координат & quot ;? вы можете найти объект svg - это вызов по положению getOffsetRect , попытка и зависимость работы объекта. – KingRider 19 October 2016 в 20:24

Я успешно использовал решение Andy E для позиционирования бутстрапа 2 в зависимости от того, какую ссылку в строке таблицы пользователь нажимает. Страница страницы Tapestry 5 и javascript ниже импортируется в классе страниц java.

javascript:

function setLinkPosition(clientId){
var bodyRect = document.body.getBoundingClientRect(),
elemRect = clientId.getBoundingClientRect(),
offset   = elemRect.top - bodyRect.top;
offset   = offset + 20;
$('#serviceLineModal').css("top", offset);

}

Мой модальный код:

<div id="serviceLineModal" class="modal hide fade add-absolute-position" data-backdrop="static" 
 tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" style="top:50%;">
<div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
    <h3 id="myModalLabel">Modal header</h3>
</div>

<div class="modal-body">
    <t:zone t:id="modalZone" id="modalZone">
        <p>You selected service line number: ${serviceLineNumberSelected}</p>
    </t:zone>
</div>

<div class="modal-footer">
    <button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
    <!-- <button class="btn btn-primary">Save changes</button> -->
</div>

Ссылка в цикле:

<t:loop source="servicesToDisplay" value="service" encoder="encoder">
<tr style="border-right: 1px solid black;">       
    <td style="white-space:nowrap;" class="add-padding-left-and-right no-border"> 
        <a t:type="eventLink" t:event="serviceLineNumberSelected" t:context="service.serviceLineNumber" 
            t:zone="pageZone" t:clientId="modalLink${service.serviceLineNumber}"
            onmouseover="setLinkPosition(this);">
            <i class="icon-chevron-down"></i> <!-- ${service.serviceLineNumber} -->
        </a>
    </td>

И код Java в классе страницы:

void onServiceLineNumberSelected(String number){
    checkForNullSession();
    serviceLineNumberSelected = number;
    addOpenServiceLineDialogCommand();
    ajaxResponseRenderer.addRender(modalZone);
}

protected void addOpenServiceLineDialogCommand() {
    ajaxResponseRenderer.addCallback(new JavaScriptCallback() {
        @Override
        public void run(JavaScriptSupport javascriptSupport) {
            javascriptSupport.addScript("$('#serviceLineModal').modal('show');");
        }
    });
}

Надеюсь, это поможет кому-то, этот пост помог.

2
ответ дан Mark Espinoza 21 August 2018 в 12:00
поделиться
  • 1
    Этот код js мне помог, у меня есть старое приложение webforms с использованием нескольких заполнителей, которые добавляют страницы .aspx, и я не мог понять, как appendChild () всплывающего окна, которое я создавал, чтобы получить его в окне просмотра, потому что все дерево DOM с несколькими заполнителями и неправильной разметкой. Используя body.getBoundingClientRect (), то использование его вершины в позиционировании было тем, что мне было нужно. Благодарю. – Brad Martin 14 August 2015 в 21:32

Хотя это, скорее всего, будет потеряно в нижней части стольких ответов, верхние решения здесь не работают для меня. Насколько я мог сказать, ни один из других ответов не помог бы. Ситуация : На странице HTML5 у меня было меню, которое было элементом навигации внутри заголовка (не заголовком, а заголовком в другом элементе). Я хотел, чтобы навигационная система придерживалась вершины, как только пользователь прокручивал ее, но до этого заголовок был абсолютно позиционирован (так что я мог бы немного наложить что-то другое). Вышеупомянутые решения никогда не приводили к изменению, потому что .offsetTop не собирался меняться, поскольку это был элемент с абсолютным позиционированием. Кроме того, свойство .scrollTop было просто вершиной верхнего элемента ..., то есть 0 и всегда было бы 0. Все тесты, которые я выполнил, используя эти два (и то же самое с результатами getBoundingClientRect), не сказали бы мне, навигационная панель когда-либо прокручивалась до верхней части просматриваемой страницы (опять же, как сообщалось в консоли, они просто оставались теми же номерами при прокрутке).

Решение Решение для меня использовало

window.visualViewport.pageTop

. Значение свойства pageTop отражает видимый раздел экрана, что позволяет мне отслеживать где элемент относится к границам видимой области.

Возможно, нет необходимости говорить, что в любое время, когда я имею дело с прокруткой, я ожидаю использовать это решение для программного реагирования на перемещение прокручиваемых элементов. Надеюсь, это поможет кому-то другому. ВАЖНОЕ ПРИМЕЧАНИЕ: Это, похоже, работает в Chrome и Opera в настоящее время & amp; определенно не в Firefox (6-2018) ... пока Firefox не поддерживает visualViewport, я рекомендую НЕ использовать этот метод (и я надеюсь, что они скоро ... это делает намного больше смысла, чем остальные). ОБНОВЛЕНИЕ: просто примечание относительно этого решения. Хотя я все еще нахожу то, что, как я обнаружил, очень ценно для ситуаций, когда «... программно реагируют на движение прокручиваемых элементов». применимо. Лучшее решение проблемы, которую я имел, это использовать CSS для установки позиции : sticky для элемента. Используя sticky, вы можете оставить элемент вверху без использования javascript (ПРИМЕЧАНИЕ: бывают случаи, когда это не будет работать так же эффективно, как изменение элемента до фиксированного, но для большинства использует липкий подход, вероятно, будет лучше) UPDATE01: Итак, я понял, что для другой страницы у меня было требование, когда мне нужно было определить положение элемента в мягкой сложной настройке прокрутки (параллакс плюс элементы, которые прокручиваются мимо как часть сообщения). В этом сценарии я понял, что следующее предоставило значение, которое я использовал, чтобы определить, когда что-то делать:

  let bodyElement = document.getElementsByTagName('body')[0];
  let elementToTrack = bodyElement.querySelector('.trackme');
  trackedObjPos = elementToTrack.getBoundingClientRect().top;
  if(trackedObjPos > 264)
  {
    bodyElement.style.cssText = '';
  }

Надеюсь, что этот ответ будет более полезен.

3
ответ дан MER 21 August 2018 в 12:00
поделиться
  • 1
    это, скорее всего, будет на вершине стольких ответов, когда вы нажмете active , чтобы отсортировать ответы – lucchi 1 June 2018 в 11:48
  • 2
    @lucchi: D ну, я полагаю, я мог бы удалить текст @ сверху ... хотя я только что вернулся на этот раз и понял, что нашел лучшее решение для своей собственной проблемы ... хотя мой ответ скорее нотную заметку к более полным ответам. Я подозреваю, что мои требования, может быть, не настолько распространены, что другие ответы не сработали для меня? – MER 1 June 2018 в 20:14
  • 3
    В любом случае, я благодарен за ваш ответ, просто нужно сказать вам, что любой желающий будет знать, что вы написали что-то новое. Ты не одинок.... – lucchi 1 June 2018 в 22:22

Это лучший код, который мне удалось создать (работает и в iframe, в отличие от смещения jQuery). Кажется, у webkit есть немного другое поведение.

Основываясь на комментарии meouw:

function getOffset( el ) {
    var _x = 0;
    var _y = 0;
    while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {
        _x += el.offsetLeft - el.scrollLeft;
        _y += el.offsetTop - el.scrollTop;
        // chrome/safari
        if ($.browser.webkit) {
            el = el.parentNode;
        } else {
            // firefox/IE
            el = el.offsetParent;
        }
    }
    return { top: _y, left: _x };
}
7
ответ дан Ron Reiter 21 August 2018 в 12:00
поделиться
  • 1
    Обратите внимание, что вам понадобится jQuery , чтобы использовать $.browser.webkit; Вам нужно будет поиграть с navigator.userAgent, чтобы сделать то же самое с чистым JavaScript. – Sathvik 7 March 2012 в 04:47
  • 2
    $ .browser больше не доступен в последней версии jQuery – Gus 12 January 2014 в 20:22
  • 3
    к сожалению, даже с FF 24.4 приведенный выше код не работает, когда границы границ существуют как часть макета позиционирования. – rob 12 May 2014 в 21:43

Вам может быть лучше, если использовать фреймворк JavaScript, который имеет функции для возврата такой информации (и многое другое!) независимо от браузера. Вот несколько:

С помощью этих фреймворков вы можете сделать что-то вроде: $('id-of-img').top, чтобы получить y- пиксельной координаты изображения.

17
ответ дан Shalom Craimer 21 August 2018 в 12:00
поделиться
  • 1
    @Costa Все они используют такие функции, хотя это развивающееся поле, поскольку разные браузеры по-разному соответствуют спецификации. Большая часть кода имеет дело с "фиксацией" вещи, которые идут не так. Вы действительно должны посмотреть на исходный код. – Shalom Craimer 27 March 2013 в 19:38
  • 2
    @scraimer: jQuery и YUI являются НЕ фреймворками !!! Это библиотеки ! Это не одно и то же. Ссылаясь на jquery.com : "jQuery - это быстрая, маленькая и многофункциональная библиотека JavaScript . & Quot; Citing yuilibrary. com (вы также можете увидеть слово «magic» в URL-адресе ...): & quot; YUI - это бесплатная библиотека JavaScript с открытым исходным кодом и CSS для построения богатого интерактивные веб-приложения. & quot; – Sk8erPeter 9 May 2013 в 12:34
  • 3
    Значит, вы должны использовать огромные библиотеки только для этой простой задачи? Не обязательно. Я ненавижу, что каждый раз, когда я хочу что-то делать с js, я получаю эти решения jQuery. jQuery не JS! – Opptatt Jobber 11 October 2013 в 20:14
  • 4
    @OpptattJobber Я согласен ... JQuery не является javascript. Он опирается на Javascript, но на другой язык программирования. – Nick Manning 27 March 2014 в 02:31
  • 5
    @NickManning Это не новый язык, его уровень абстракции для DOM, который устраняет необходимость писать совместимость и обходные пути производительности непосредственно в ваш код. Если вы не используете jQuery, вы должны использовать какой-то уровень абстракции. – ginman 4 April 2014 в 16:01

Получить позицию div по отношению к левому и верхнему

  var elm = $('#div_id');  //get the div
  var posY_top = elm.offset().top;  //get the position from top
  var posX_left = elm.offset().left; //get the position from left 
0
ответ дан Vishal 21 August 2018 в 12:00
поделиться
  • 1
    Я проголосовал за то, что нижнее и правое не являются свойствами смещения () – MacroMan 8 May 2018 в 14:39
  • 2
    @MacroMan, я уважаю ваше решение, но я уже объяснил в тексте, что «нижний и правый код не проверен». Кроме того, я скоро обновлю свой код. – Vishal 8 May 2018 в 16:56
  • 3
    Я думаю, что это el.offsetTop и el.offsetLeft (OP ничего не говорит о jQuery ... Я не уверен, почему ваш ответ использует jQuery либо ...) – mesqueeb 10 July 2018 в 06:57
1
ответ дан Asif J 1 November 2018 в 05:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: