javascript - 화면 - HTML 요소의 위치(X, Y) 검색




태그 위치 (16)

JavaScript에서 imgdiv 와 같은 HTML 요소의 X 및 Y 위치를 얻는 방법을 알고 싶습니다.


왼쪽과 위쪽에 대한 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 

jQuery .offset() 은 첫 번째 요소의 현재 좌표를 가져 오거나 일치하는 요소 집합의 모든 요소 좌표를 문서와 관련하여 설정합니다.


그냥 내가 거기 밖으로 던질 줄 알았는데.
나이가 든 브라우저에서 테스트 할 수는 없지만 최신 톱 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()};
};

나는 @ meouw의 대답을 취했다. 클라이언트 왼쪽에 추가하여 경계를 허용 한 다음 세 가지 버전을 만들었다.

getAbsoluteOffsetFromBody - @ meouw 's와 비슷하게 문서의 body 또는 html 요소에 상대적인 절대 위치를 가져옵니다 (단점 모드에 따라 다름)

getAbsoluteOffsetFromGivenElement - 주어진 엘리먼트 (relativeEl)를 기준으로 절대 위치를 반환합니다. 지정된 엘리먼트는 엘리먼트 el을 포함해야하며, 그렇지 않으면 getAbsoluteOffsetFromBody와 동일하게 동작합니다. 이는 두 개의 요소가 다른 (알려진) 요소에 포함되어 있고 (선택적으로 노드 트리를 구성하는 여러 노드) 동일한 위치로 만들고 싶을 때 유용합니다.

getAbsoluteOffsetFromRelative - position : relative를 가진 첫 번째 부모 요소를 기준으로 절대 위치를 반환합니다. 이는 같은 이유로 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=331http://www.greywyvern.com/?post=331 수 있습니다. 브라우저에서 동작한다고 가정 할 때 getStyle에 의심스러운 코드가 하나 이상 있음을 발견했습니다. , 나머지는 전혀 테스트하지 않았습니다.


다른 브라우저는 테두리, 여백, 여백 등을 다른 방식으로 렌더링하기 때문에. 정확한 차원에서 원하는 모든 루트 요소에서 특정 요소의 위쪽 및 왼쪽 위치를 검색하는 약간의 함수를 작성했습니다.

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

왼쪽 위치를 검색하려면 다음을 반환해야합니다.

    return offsetRect.left - rootRect.left;

당신이 jQuery를 사용한다면, 이것은 간단한 해결책이 될 수 있습니다 :

<script>
  var el = $("#element");
  var position = el.position();
  console.log( "left: " + position.left + ", top: " + position.top );
</script>

대부분의 브라우저에서 HTML 요소는 다음을 갖습니다.

offsetLeft
offsetTop

이것들은 레이아웃이있는 가장 가까운 부모를 기준으로 요소의 위치를 ​​지정합니다. 이 부모는 종종 offsetParent 속성을 통해 액세스 할 수 있습니다.

IE와 FF3이 있습니다.

clientLeft
clientTop

이러한 속성은 덜 일반적이며 부모 클라이언트 영역과 함께 요소 위치를 지정합니다 (패딩 된 영역은 클라이언트 영역의 일부이지만 테두리 및 여백은 그렇지 않습니다).


라이브러리는 요소에 대한 정확한 오프셋을 얻기 위해 일정 길이로갑니다.
여기 제가 시도한 모든 상황에서 그 일을하는 간단한 기능이 있습니다.

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; 

브라우저 프레임과 같은 방식으로 정보를 반환하는 기능이있는 JavaScript 프레임 워크를 사용하면 더 효과적 일 수 있습니다. 다음은 몇 가지 예입니다.

이러한 프레임 워크를 사용하면 $('id-of-img').top 을 사용하여 이미지의 y 픽셀 좌표를 얻을 수 있습니다.


엘리먼트의 ID를 전달함으로써 이런 식으로하면 왼쪽이나 위를 반환 할 것이고 그것들을 결합 할 수도 있습니다 :

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');

이것은 나를 위해 일했습니다 (가장 높은 투표 응답에서 수정 됨) :

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

이것을 사용하여 우리는 부를 수있다.

getOffset(element).left

또는

getOffset(element).top

이것은 내가 작성한 최고의 코드입니다 (jQuery의 offset ()과 달리 iframe에서도 작동합니다). 웹킷에는 약간 다른 동작이있는 것 같습니다.

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 };
}

이전 브라우저와 호환되기 때문에 이렇게했습니다.

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


작고 작은 차이점

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


페이지에 적어도 "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];
};


필자는 Andy E의 솔루션을 사용하여 사용자가 클릭하는 테이블 행의 링크에 따라 부트 스트랩 2 모달을 배치했습니다. 이 페이지는 Tapestry 5 페이지이며 아래 자바 스크립트는 자바 페이지 클래스로 가져옵니다.

자바 스크립트 :

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>

그리고 페이지 클래스의 자바 코드 :

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');");
        }
    });
}

희망이 사람을 도울,이 게시물 도왔습니다.





position