본문 바로가기

JavaScript

스크롤 위치에 따른 오브젝트 조작

홈페이지를 만들 때 스크롤에 따른 이벤트는 아주 많이 사용된다.

지금까진 제대로 컨트롤하는 방법을 몰라서 라이브러리 등을 사용해서 만들었는데, 요즘 트렌드에는 스크롤 이벤트가 워낙 많이 들어가서 직접 사용하는 방법에 대해서 알아보려고 한다. 

 

특정 라이브러리가 아닌 순수 자바스크립트의 기능을 사용해서 구현해보려고 한다. 

 

속성

이벤트를 구현하기 전에 사용할 수 있는 속성이 어떤 것들이 있는지 알아보자. 

(function () {
  const outputEle = document.querySelector(".output");

  window.addEventListener("scroll", function (e) {
    outputEle.innerHTML = window.innerHeight;
  });
})();

window의 innerHeight 속성은 화면의 높이를 나타낸다. 

화면에 높이라는 것이 보이는 영역을 나타내는데 스크롤의 크기가 아니다. 

파란색 영역이 스크롤의 크기를 나타낸다면 붉은 영역이 innerHeight 보이는 영역의 높이를 나타낸다. 

(function () {
  const outputEle = document.querySelector(".output");

  window.addEventListener("scroll", function (e) {
    outputEle.innerHTML = window.scrollY;
  });
})();

window의 scrollY 속성은 최상단에서부터 스크롤을 얼마나 이동했는지 나타내는 속성이다. 

(function () {
  const outputEle = document.querySelector(".output");
  const ilbuniEle = document.querySelector(".ilbuni");

  window.addEventListener("scroll", function (e) {
    outputEle.innerHTML = ilbuniEle.offsetTop;
  });
})();

특정 요소의 offsetTop 속성은 최상단에서부터 특정 요소까지의 거리가 얼마인지 알 수 있는 속성이다. 

(function () {
  const outputEle = document.querySelector(".output");
  const ilbuniEle = document.querySelector(".ilbuni");

  window.addEventListener("scroll", function (e) {
    console.log(ilbuniEle.getBoundingClientRect());
    outputEle.innerHTML = ilbuniEle.getBoundingClientRect().top;
  });
})();

특정 요소의 getBoundingClientRect 속성은 특정 요소가 화면에서 어느정도의 위치에 있는지를 나타낸다. 

객체를 리턴하는데, 내부 속성으로는 bottom, top, left, right, width, height, x, y가 있다. 

bottom, top, left, right는 현재 화면에서 요소가 어느 위치에 존재하는지를 나타낸다. 

x와 y는 각각 left와 top을 나타내는 또다른 명칭이다. width와 height은 명칭 그대로 요소의 크기를 나타낸다. 

이 함수를 활용하면 실시간으로 요소가 어느위치에 존재하는 확인하기가 쉬워진다. 

 

스크롤 이벤트

캐릭터의 위치가 브라우저의 1/4 위치에 오게되면 크기를 키우는 이벤트를 만들어보자. 

(function () {
  const outputEle = document.querySelector(".output");
  const ilbuniEle = document.querySelector(".ilbuni");

  function showValue() {
    return ilbuniEle.getBoundingClientRect().top;
  }

  window.addEventListener("scroll", function (e) {
    const posY = showValue();

    outputEle.innerHTML = posY;

    if (posY < window.innerHeight / 4) {
      ilbuniEle.classList.add("zoom");
    }
  });
})();

위에서부터 코드를 하나씩 살펴보면 아래와 같다. 

function showValue() {
  return ilbuniEle.getBoundingClientRect().top;
}

캐릭터의 위치가 어디에 존재하는지 알려주는 코드를 따로 함수로 빼두었다. 

window.addEventListener("scroll", function (e) {
  const posY = showValue();

  outputEle.innerHTML = posY;

  if (posY < window.innerHeight / 4) {
    ilbuniEle.classList.add("zoom");
  }
});

스크롤 이벤트가 발생 했을 때 캐릭터의 위치(showValue)를 확인하고 화면의 높이(innerHeight)의 1/4 위치보다 작으면 zoom 이라는 클래스를 줘서 캐릭터가 커지도록 작업했다. 

 

zoom 클래스는 미리 설정해둔 속성으로 scale을 2배로 올려주는 스타일을 가지고 있다. 

스크롤을 다시 올렸을 때 커진 캐릭터다 다시 작아져야 하기 때문에 else 문에서 zoom 클래스를 빼주면 완성이다. 

(function () {
  const outputEle = document.querySelector(".output");
  const ilbuniEle = document.querySelector(".ilbuni");

  function showValue() {
    return ilbuniEle.getBoundingClientRect().top;
  }

  window.addEventListener("scroll", function (e) {
    const posY = showValue();

    outputEle.innerHTML = posY;

    if (posY < window.innerHeight / 4) {
      ilbuniEle.classList.add("zoom");
    } else {
      ilbuniEle.classList.remove("zoom");
    }
  });
})();

 

반응형

'JavaScript' 카테고리의 다른 글

RequestAnimationFrame  (6) 2024.10.12
Transition & Animation 이벤트  (3) 2024.10.09
얕은 복사 & 깊은 복사  (3) 2024.09.25
Object  (1) 2024.09.21
호이스팅  (1) 2024.08.21