본문 바로가기
dev/javascript

[javascript] 자바스크립트 getBoundingClientRect (size, position)

by 최연탄 2023. 5. 10.
728x90
반응형

참고: https://www.golinuxcloud.com/javascript-getboundingclientrect/

JavaScript의 getBoundingClientRect() 메소드는 웹페이지 요소의 위치와 크기를 알아내고자 할 때 사용합니다. 이는 뷰포트(웹 페이지의 보이는 부분)에서 요소의 위치와 크기를 가져옵니다. 리턴 값으로 다음과 같은 속성을 반환합니다.

  • left: 뷰포트의 왼쪽에서 요소의 왼쪽 부분까지의 거리
  • top: 뷰포트의 위쪽에서 요소의 위쪽 까지의 거리
  • right: 뷰포트의 오른쪽와 요소의 오른쪽 사이 거리
  • bottom: 뷰포트의 아래쪽과 요소의 아래쪽 거리
  • width: pixel 단위의 요소의 가로 크기
  • height: pixel 단위 요소의 세로 크기
<div id="myDiv">
  <p>This is some text inside the div.</p>
</div>

<script>
  var myDiv = document.getElementById("myDiv");
  var rect = myDiv.getBoundingClientRect();
  console.log(rect.left);
  console.log(rect.top);
  console.log(rect.width);
  console.log(rect.height);
</script>

위의 예제에서는 id를 사용해 div 요소를 가져온 다음 getBoundingClientRect() 메소드를 사용해 div 요소의 위치와 크기를 가져왔습니다. 그 다음 console.log()를 사용해 left, top, width, height 속성을 콘솔에 출력했습니다.

간단한 getBoundingClientRect() 메소드 사용 예제

예제 1: 이미지의 가로 세로 크기 가져오기

이 예제에서는 getBoundingClientRect()를 사용하여 이미지의 가로 크기와 세로 크기를 얻어보겠습니다. 먼저 id로 이미지 요소를 가져온 후 getBoundingClientRect() 메소드를 호출합니다. 여기서 리턴된 객체는 픽셀 단위의 이미지 가로, 세로 크기를 포함하고 있습니다.

<img id="myImage" src="https://images.pexels.com/photos/16415740/pexels-photo-16415740.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1">

<script>
  window.onload = () => {
    var myImage = document.getElementById("myImage");
    var rect = myImage.getBoundingClientRect();
    console.log(rect.width);
    console.log(rect.height);
  }
</script>

예제 2: 요소의 위치 알아내기

이 예제에서는 getBoundingClientRect()를 이용하여 div의 위치를 가져오겠습니다. 먼저 div 요소를 id를 통해 가져온 후 getBoundingClientRect() 메소드를 호출합니다. 그럼 리턴 값으로 뷰포트로부터의 거리인 left와 top이 포함된 객체를 얻을 수 있습니다.

<div id="myDiv">
  <p>This is some text inside the div.</p>
</div>

<script>
  var myDiv = document.getElementById("myDiv");
  var rect = myDiv.getBoundingClientRect();
  console.log(rect.left);
  console.log(rect.top);
</script>

예제 3: 요소가 뷰포트에 표시되는지 여부 확인

<div id="myDiv">
  <p>This is some text inside the div.</p>
</div>

<script>
  var myDiv = document.getElementById("myDiv");
  var rect = myDiv.getBoundingClientRect();
  var isVisible = (rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth));
  console.log(isVisible);
</script>

이 예제에서는 getBoundingClientRect()를 사용해 div가 뷰포트에서 보이는지 여부를 확인해 보겠습니다. 먼저 id로 div 요소를 얻은 후 getBoundingClientRect() 메소드를 호출하면 리턴 값으로 div의 top, left, bottom, right 값을 얻어서 뷰포트에 요소가 보이고 있는지 여부를 확인할 수 있습니다. 만약 top, right, bottom, left 값이 모두 0보다 같거나 크고, 가로/세로 크기가 뷰포트의 가로/세로 보다 작으면 이는 요소가 뷰포트에 표시되고 있다는 의미입니다.

복잡한 getBoundingClientRect() 메소드 사용 예제

getBoundingClientRect() 메소드는 div, p, img 같은 어떤 DOM 요소에서도 호출할 수 있습니다. 그리고 동적인 대화형 웹 페이지를 만들기 위해 scrollTop, offsetWidth, clientHeight 같은 다른 JavaScript 메소드/속성과 함께 사용할 수 있습니다.

예제 1: 요소 위치 고정

getBoundingClientRect()의 일반적인 사용 사례 중 하나는 사용자가 스크롤해도 페이지 상단에 붙어있는 고정 네비게이션 바를 만드는 것 입니다. 이를 하려면 먼저 document.querySelector()를 사용하여 네비게이션 바에 대한 참조를 얻은 다음 getBoundingClientRect()를 사용하여 요소의 위치를 얻습니다. 그런 다음 이벤트리스너를 이용하여 사용자가 스크롤 할 때를 감지하여 scrollTop 속성으로 스크롤된 거리를 계산하고 style.top 속성을 사용하여 네비게이션 바를 상단에 계속 위치하도록 위치를 설정합니다.

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>javascript getBoundingClientRect</title>
  <style>
    p {
      width: 100px;
    }
    .navbar {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      background-color: rgb(155, 19, 19);
      color: #fff;
      padding: 10px;
    }
    .content {
      margin-top: 40px;
    }
  </style>
</head>

<body>
  <nav class="navbar">
    <a href="#">Home</a>
    <a href="#">About</a>
    <a href="#">Contact</a>
  </nav>
  <div class="content">
    <p>
      Lorem ipsum dolor sit amet, consectetur adipisicing elit.
      Doloremque corporis omnis sint cumque ut, laudantium facilis,
      voluptatum qui laborum ipsa consequatur, vitae nihil cupiditate
      ...
      inventore voluptates. Architecto nam cupiditate praesentium?
    </p>
  </div>
  <script>
    const navbar = document.querySelector(".navbar");
    const navbarRect = navbar.getBoundingClientRect();

    window.addEventListener("scroll", () => {
      const scrollTop = window.pageYOffset || document.documentElement.scrollTop;

      navbar.style.top = -`${navbarRect.top + scrollTop}px`;
    });
  </script>
</body>

</html>

예제 2: 반응형 디자인

getBoundingClientRect()의 다른 사용 사례는 반응형 디자인 입니다. getBoundingClientRect()를 사용하여 요소의 위치와 크기를 얻은 다음 offsetWidth 및 clientHeight 속성을 사용하여 뷰포트의 크기를 계산할 수 있습니다. 그 다음 media query를 사용하여 뷰포트의 크기에 따라 다른 CSS 스타일을 적용할 수 있습니다.

const element = document.querySelector(".my-element");
const rect = element.getBoundingClientRect();

const viewportWidth = rect.width;
const viewportHeight = rect.height;

if (viewportWidth > 800) {
    // 큰 화면에 대한 스타일
} else {
    // 작은 화면에 대한 스타일
}

예제 3: 헤더를 뷰포트 상단에 고정

이번 예제에서는 getBoundingClientRect()를 사용하여 사용자가 페이지를 아래로 스크롤 할 때 헤더를 뷰포트 상단에 고정합니다. 먼저 id로 헤더 요소를 가져온 다음 getBoundingClientRect() 메소드를 호출하여 초기 위치를 가져옵니다. 그 다음 addEventListener() 메소드를 사용하여 window에서 스크롤 이벤트를 감지합니다. 이벤트리스너 함수 내에서 getBoundingClientRect()를 다시 사용하여 헤더의 현재 위치를 가져옵니다. 헤더의 top 값이 0 보다 작으면 뷰포트 밖으로 스크롤 되었다는 뜻이므로 top을 0으로 설정하여 상단에 고정합니다. top 값이 0 보다 크거나 같으면 헤더가 여전히 뷰포트에 있음을 의미하므로 top 위치를 다시 초기 위치로 설정합니다.

<header id="myHeader">
  <h1>My Website</h1>
  <nav>
    <a href="#">Home</a>
    <a href="#">About</a>
    <a href="#">Contact</a>
  </nav>
</header>

<div class="content">
  <p>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit.
    Doloremque corporis omnis sint cumque ut, laudantium facilis,
    voluptatum qui laborum ipsa consequatur, vitae nihil cupiditate
    inventore voluptates. Architecto nam cupiditate praesentium?
  </p>
</div>

<style>
  #myHeader {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 1;
  }
  .content {
    width: 100px;
    margin-top: 100px;
  }
</style>

<script>
  var myHeader = document.getElementById("myHeader");
  var rect = myHeader.getBoundingClientRect();
  var initialTop = rect.top;

  window.addEventListener("scroll", function () {
    var rect = myHeader.getBoundingClientRect();
    if (rect.top < 0) {
      myHeader.style.top = "0px";
    } else {
      myHeader.style.top = initialTop + "px";
    }
  });
</script>

예제 4: Lazy Load Images

이 예제에서는 getBoundingClientRect()를 사용하여 웹 페이지에서 이미지를 지연 로딩 해보겠습니다. 먼저 querySelectorAll()을 사용하여 "lazy" 클래스를 가진 모든 이미지를 가져오고 lazyImages 라는 변수에 저장합니다. 그런 다음 이미지가 뷰포트에 있는지 확인하기위해 checkInView() 라는 함수를 만듭니다. 함수 내에서 forEach()를 사용하여 루프돌며 이미지에서 getBoundingClientRect()를 호출하여 위치를 가져옵니다. 이미지의 top, right, bottom, left 값이 뷰포트 내에 있는지 확인하고 뷰포트 내에 있다면 이미지의 src 속성을 data-src 속성 값으로 설정합니다. 그러면 이미지가 로드됩니다. 마지막으로 addEventListener() 메소드를 사용하여 window에서 load, resize, scroll 이벤트를 수신하고 이 이벤트가 발생할 때 마다 checkInView() 함수를 호출합니다.

<img class="lazy" data-src="https://images.pexels.com/photos/14966037/pexels-photo-14966037.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1">
<img class="lazy" data-src="https://images.pexels.com/photos/16415740/pexels-photo-16415740.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1">
<img class="lazy" data-src="https://images.unsplash.com/photo-1682418408515-18655b74d784?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1287&q=80">

<script>
  var lazyImages = document.querySelectorAll(".lazy");

  function checkInView() {
    lazyImages.forEach(function (image) {
      var rect = image.getBoundingClientRect();
      if (rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth)) {
        image.src = image.dataset.src;
      }
    });
  }

  window.addEventListener("load", checkInView);
  window.addEventListener("resize", checkInView);
  window.addEventListener("scroll", checkInView);
</script>

정리

getBoundingClientRect() 메소드는 개발자가 웹 페이지 요소의 위치와 크기를 가져올 수 있는 강력한 JavaScript 메소드입니다. 동적이나 대화형 웹 페이지를 만들기 위해 다른 JavaScript 메소드 및 속성과 함께 사용되며 다양한 화면 크기에 적응하는 반응형 디자인을 만드는 데 사용할 수 있습니다.

관련 글

자바스크립트 addEventListener 사용 방법

자바스크립트 getElementById 사용 방법

자바스크립트 querySelector 사용 방법

반응형

댓글