Development Tip

스크롤하는 동안 JavaScript getBoundingClientRect () 변경

yourdevel 2020. 12. 15. 19:50
반응형

스크롤하는 동안 JavaScript getBoundingClientRect () 변경


문서의 상단으로 간주하는 요소의 Y 좌표와 Y 값 = 0 사이의 정확한 거리를 원합니다.

myElement.getBoundingClientRect().top;

그러나 스크롤하는 동안 getBoundingClientRect () 값이 변경되는 것 같습니다. myElement와 Y 좌표 = 0 (문서 상단) 사이의 실제 거리를 어떻게 알 수 있습니까?


(전체 페이지)가 아닌 ( 페이지의 현재 보이는 부분 만)에 getBoundingClientRect()대한 값을 가져 오기 때문 입니다. 따라서 기본적으로 값을 계산할 때 스크롤을 고려합니다 .windowdocument

document = window + scroll

따라서 myElement와 Y 좌표 = 0 (문서 맨 위) 사이의 거리를 얻으려면 세로 스크롤 값도 추가해야합니다.

myElement.getBoundingClientRect().top + window.scrollY;

출처 : https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect


getBoundingClientRect는 scrollY / pageYOffset의 버그를 피하기 위해 좀 더주의가 필요합니다.

function absolutePosition(el) {
    var
        found,
        left = 0,
        top = 0,
        width = 0,
        height = 0,
        offsetBase = absolutePosition.offsetBase;
    if (!offsetBase && document.body) {
        offsetBase = absolutePosition.offsetBase = document.createElement('div');
        offsetBase.style.cssText = 'position:absolute;left:0;top:0';
        document.body.appendChild(offsetBase);
    }
    if (el && el.ownerDocument === document && 'getBoundingClientRect' in el && offsetBase) {
        var boundingRect = el.getBoundingClientRect();
        var baseRect = offsetBase.getBoundingClientRect();
        found = true;
        left = boundingRect.left - baseRect.left;
        top = boundingRect.top - baseRect.top;
        width = boundingRect.right - boundingRect.left;
        height = boundingRect.bottom - boundingRect.top;
    }
    return {
        found: found,
        left: left,
        top: top,
        width: width,
        height: height,
        right: left + width,
        bottom: top + height
    };
}

피해야 할 버그는 다음과 같습니다.

  • Chrome Mobile 43 에 scrollY / pageYOffset 잘못되어 있기 때문에 Android Chrome에서 스크롤합니다 (특히 키보드가 표시되고 스크롤 할 때).

  • Microsoft IE 또는 Edge의 핀치 확대로 인해 scrollY / pageYOffset에 잘못된 값이 발생 합니다 .

  • 일부 (구식) 브라우저에는 높이 / 너비가 없습니다 (예 : IE8)

Edit: The above code can be simplified a lot by just using document.body.getBoundingClientRect() instead of adding a div - I haven't tried it though so I am leaving my answer as it stands. Also the body needs margin:0 (reset.css usually does this). This answer simplifies the code down a lot, while still avoiding the bugs in jQuery.offset()!

Edit 2: Chrome 61 introduced window.visualViewport to give correct values for the actual viewport which is probably another way to fix issues; but beware that Android Chrome 66 was still buggy if Settings -> Accessability -> Force enable zoom was ticked (bugs with orientation change, focused inputs, absolutely positioned popup wider than viewport).

ReferenceURL : https://stackoverflow.com/questions/25630035/javascript-getboundingclientrect-changes-while-scrolling

반응형