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

ZeroToHunnit Coding

[Javascript] 내용은 스크롤 되고 고정된 부분의 사진 바뀜 본문

JAVASCRIPT

[Javascript] 내용은 스크롤 되고 고정된 부분의 사진 바뀜

0에서100 2024. 1. 16. 15:37
728x90
반응형

사진 부분은 고정되어 있지만 컨텐츠에 따라서 사진이 바뀌는 ui를 만들어보았다.

 

HTML

  <div class="section">
    <div class="sticky">
      <div class="img opacity1">
        <p>1번 이미지</p>
      </div>
      <div class="img">
        <p>2번 이미지</p>
      </div>
      <div class="img">
        <p>3번 이미지</p>
      </div>
      <div class="img">
        <p>4번 이미지</p>
      </div>
    </div>
    <div class="content-box">
      <div class="content">
        <p>1번 컨텐츠</p>
      </div>
      <div class="content">
        <p>2번 컨텐츠</p>
      </div>
      <div class="content">
        <p>3번 컨텐츠</p>
      </div>
      <div class="content">
        <p>4번 컨텐츠</p>
      </div>
    </div>
  </div>

 

우선 이미지 부분과 컨텐트 부분의 큰 div를 만들고 안에 갯수에 맞게 작은 div들을 만들어주었다.

 

CSS

body, html{
  contain: paint;
}

.section{
  width: 100vw;
  height: 400vh;
  margin-top: 500px;
  margin-bottom: 500px;
  display: flex;
}

.sticky{
  position: sticky;
  width: 50vw;
  height: 100vh;
  top: 0;
  left: 0;
}

.img{
  position: absolute;
  width: 50vw;
  height: 100vh;
  top: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 60px;
  opacity: 0;
  transition: all 0.3s;
}

.img:nth-child(1){
  background-color: aqua;
}

.img:nth-child(2){
  background-color: red;
}

.img:nth-child(3){
  background-color: yellow;
}

.img:nth-child(4){
  background-color: green;
}

.content-box{
  width: 50vw;
  height: 100vh;
}

.content{
  width: 50vw;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 60px;
}

.opacity1{
  opacity: 1;
}

우선 img를 담은 큰 div는 position:sticky를 걸어주고 img들은 position:absolute로 한 곳에 겹치게 해두었다. 그리고 opacity1이라는 클래스를 미리 만들어 opacity:1을 설정해두고 평소에 img들은 opacity:0으로 설정해둔다.

 

JAVASCRIPT

let viewHeight = document.querySelector('html').clientHeight;
const content = document.querySelectorAll('.content');
const img = document.querySelectorAll('.img');

window.addEventListener('scroll',function(){
if(content[0].getBoundingClientRect().top < viewHeight/2){
  img[0].classList.add('opacity1');
}

for(i = 1; i < content.length - 1; i++){
  if(content[i].getBoundingClientRect().top < viewHeight/2 && content[i].getBoundingClientRect().top > -viewHeight/2){
    img[i].classList.add('opacity1');
  } else{
    img[i].classList.remove('opacity1');
  }
}

if(content[content.length - 1].getBoundingClientRect().top < viewHeight/2){
  img[content.length - 1].classList.add('opacity1');
} else{
  img[content.length - 1].classList.remove('opacity1');
}
});

반복되는 설렉터들은 변수에 우선 담아두고 스크롤 이벤트리스너를 사용해서 처음 부분과 끝 부분은 따로 설정해두고 중간 div들만 for반복문을 써주었다. 각 content가 화면상 중간값에 도달하게 되면 클래스를 부여했다가 제거했다가 하는 방식으로 만들었다.

 

처음과 끝 부분을 따로 떼어놓은 이유는 모두가 동일하게 for반복문 안에 넣게되면 첫 img div가 화면상 중간값에 도달할 때까지 아무것도 보이지 않고, 마지막 img div또한 중간값을 벗어나게 되면 아무것도 보이지 않기 때문에 처음과 끝은 섹션 영역을 벗어나더라도 보이게 하기 위해 따로 코드를 짜두었다.

 

이번에도 또한 하드코딩으로 모두 구현시켜놓은 후 변수와 for반복문을 사용하면서 코드를 줄여나가는 방식으로 했다. 그리고 확장성 좋게 코드를 짜보려고 생각을 많이 했다. 위의 코드는 컨텐츠들이 몇 개가 늘어나도 따로 더 코드를 짜지 않아도 잘 작동한다. 0번째는 무조건 0번째니까 0으로 하드코딩했지만 마지막번째는 content 갯수 -1개를 하면 무조건 마지막 div가 선택되기 때문에 확장성이 좋다고 할 수 있다.

 

하드코딩으로 기능을 먼저 구현하고 나서 변수와 반복문을 도입하여 코드를 리팩토링하는 방법을 사용했다. 이는 아주 전력적이고 효과적인 코딩 방법이라고 할 수 있다. 초기에 기능을 구현함으로써 전체적인 흐름과 로직을 빠르게 이해할 수 있으며, 이후에 코드를 리팩토링하면서 중복을 줄이고 유연성을 높일 수 있다.

이러한 접근 방식은 코드를 단계적으로 개선할 수 있는 장점을 제공한다. 처음에는 명확한 동작을 보장하기 위해 하드코딩을 사용하고, 이후에는 코드의 가독성과 확장성을 고려하여 변수와 반복문을 도입하는 것이 좋다.

이 방법은 코드를 빠르게 개발하면서도 향후 유지보수 및 확장이 쉽도록 하는 방식으로, 실제로 많은 프로젝트에서 채용되는 전략 중 하나다. 계속해서 코드를 개선하고 보다 모듈화된 구조로 만들어 나가는 노력은 코드의 품질과 유지보수성을 향상시킬 수 있다.

 

하드코딩을 최소화하고 변수와 반복문을 통해 코드를 보다 유연하게 만드는 것은 좋은 프로그래밍 습관 중 하나다. 이렇게 확장성 있고 유지보수가 용이한 코드를 작성하는 것은 프로젝트의 효율성을 향상시킬 수 있다.

마지막 번째 요소를 선택할 때 content 갯수에 -1을 적용하여 새로운 컨텐츠가 추가되더라도 코드 수정이 필요하지 않다.

더불어, 코드를 짧게 유지하면서도 가독성을 유지하는 것도 중요하다. 코드의 가독성이 높으면 다른 개발자들이나 여러 시점에서 코드를 이해하고 수정하기가 훨씬 쉬워진다.

728x90
반응형