반응형
250x250
Notice
Recent Posts
Recent Comments
Link
관리 메뉴

ZeroToHunnit Coding

[Javascript] 가로 스크롤 시 해당 섹션의 제목 고정 본문

JAVASCRIPT

[Javascript] 가로 스크롤 시 해당 섹션의 제목 고정

0에서100 2024. 2. 7. 23:11
728x90
반응형

위와 같이 가로(좌우)스크롤 시 각 섹션이 안보일 때까지 해당 제목이 고정되는 ui를 만들어보았다.

 

HTML

  <div class="section">
    <div class="scroll">
      <div class="box">
        <div class="content">
          <h1 class="title">1번 컨텐츠입니당</h1>
          <div class="photo"></div>
        </div>
      </div>
      <div class="box">
        <div class="content">
          <h1 class="title">2번 컨텐츠입니당</h1>
          <div class="photo"></div>
        </div>

      </div>
      <div class="box">
        <div class="content">
          <h1 class="title">3번 컨텐츠입니당</h1>
          <div class="photo"></div>
        </div>
      </div>
    </div>
  </div>

 

CSS

body, html{
  contain: paint;
}

.section{
  width: 100%;
  height: 3000px;
  position: relative;
  margin: 500px 0;
}

.scroll{
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: space-between;
  position: sticky;
  top: 0;
  left: 0;
}

.box{
  padding: 0 60px;
  width: 1400px;
  height: 700px;
}

.title{
  margin-bottom: 60px;
}

.photo{
  width: 1300px;
  height: 500px;
  background-color: aquamarine;
}

scroll div의 width를 좌우로 크게 잡고 position:sticky를 통해 해당 섹션에 들어왔을 때 고정되게 했다.

 

JAVASCRIPT

window.addEventListener('scroll',function(){
  let scrollHorizon = -27/20 * window.scrollY + 675;

  if(window.scrollY > 500 && window.scrollY < 2500){
    document.querySelector('.scroll').style.transform = `translateX(${scrollHorizon}px)`
  }

  if(window.scrollY > 500 && window.scrollY < 1260){
    document.querySelectorAll('.title')[0].style.transform = `translateX(${-scrollHorizon}px)`;
  }

  if(window.scrollY > 1300 && window.scrollY < 2060){
    document.querySelectorAll('.title')[1].style.transform = `translateX(${-scrollHorizon - 1080}px)`;
  }

  if(window.scrollY > 2100 && window.scrollY < 2500){
    document.querySelectorAll('.title')[2].style.transform = `translateX(${-scrollHorizon - 2160}px)`;
  }

  if(window.scrollY < 500){
    document.querySelector('.scroll').style.transform = `translateX(0px)`
    document.querySelectorAll('.title')[0].style.transform = `translateX(0px)`
  }
})

우선 코드가 상당히 더럽다. 확장성도 없고 if문이 난무해서 솔직히 이거 짜면서 이게 맞나 생각이 많이 들었지만 고민해도 다른 방안이 떠오르지 않아 일단 구현만 했다.

 

스크롤 이벤트리스너를 써서 position:sticky 구간에서 좌우로 스크롤되게 구현한 후, 스크롤과 box의 값으로 title이 고정되도록 보이게 했다. 고정한 것처럼 보이지만 사실 box가 좌로 움직일 때 title은 우로 움직이게 해서 가만히 있는 것처럼 편법(?)을 쓴 것이다.

 

처음에 title을 어떻게 고정시키지 고민하면서 처음에는 title의 일차방정식을 따로 구해서 해봤는데 scroll div의 스크롤 속도와 title div의 스크롤 속도가 달라서 고정되어있는 것처럼 보이지 않길래 1차 실패했다.

 

2차로 position:fixed를 이용해서 클래스 부여하는 식으로 짜봤는데 ui가 움직여서 실패했는데 지금 보니까 title에 margin-bottom을 주지 않고 photo에 margin-top을 줬으면 잘 되지 않았을까 하는 생각이 든다. 그러면 또 title이 box의 우측 끝에 닿았을 때 어떻게 구현해야할지도 고민해봤어야 됐다. 다음에 fixed로 한 번 더 공부해봐야겠다.

 

3차로 photo의 우측값을 구해서 (getboundingrect().right) title을 그에 맞게 움직이고 고정시켜보려고 했지만 생각대로 잘 되지 않았다.

 

그렇게 마지막으로 속도가 같으려면 scrollHorizon변수를 음수값으로 하면 되겠구나를 생각했고 window.scrollY값과 photo의 움직이는 값을 맞춰서 구간을 나누면 얼추 맞겠구나 하고 해봤더니 구현은 가능했다. 근데 생각보다 코드가 너무 더러웠다.

 

마지막에 window.scrollY < 500 조건을 준 이유는 이상하게 스크롤을 다 내리고 다시 올리면 translateX값이 10px정도가 남아서 그냥 0px로 되게 했다.

 

처음에 이걸 만들 때 좌우 스크롤되면서 제목도 고정되면 사람들이 내용을 보면서 제목도 계속 같이 보이니까 좀 기억에 잘 남는 ui가 되지 않을까 생각했는데 코드를 보면 굳이 저렇게까지 해야될까라는 생각이 들기도 한다. 혹시나 저걸 쓸 일이 생긴다면 좀 더 고민해서 더럽지 않고 확장성있는 코드를 짜봐야겠다. 그래도 여러 실패를 겪으면서 생각하는 폭이 조금은 넓어진 것같다.

728x90
반응형