코딩 기록/코딩 소스 [HTML & CSS & JS]

자바스크립트 Sticky 기능 구현 예제 [Javascript & jQuery]

kimyang-Sun 2023. 1. 26. 20:51

자바스크립트 (JavaScript)

 

See the Pen Sticky 기능(자바스크립트) 자체 커스텀 코드 by kimyangsun (@kimyangsun) on CodePen.

 

자바스크립트 Sticky 기능 구현 예제 [Javascript & jQuery] 코드펜 소스코드 입니다.

해당 기능을 구현할때 다른 쉬운 코드들이 있을수도 있겠지만 저 나름대로 최대한 간단하게 짜본 코드입니다.

변수로 지정된 요소들과 if 문을 잘 살펴보시면 이해하기 편하실거에요 :)

바닐라 자바스크립트 코드와 제이쿼리로 작업하시는 분들을 위해서 제이쿼리 코드도 같이 올립니다 ㅎ.ㅎ

 

/* 바닐라 자바스크립트 */
window.addEventListener('scroll', function() {
  const PADDING = 20; // 스티키 박스가 고정될 때 공백 간격
  
  let scrollTop = window.scrollY;
  // console.log('윈도우의 scrollTop : ' + scrollTop);
  
  let breakOffsetTop = document.querySelector('.break-anchor').offsetTop;
  let breakDistance = document.querySelector('.break-anchor').getBoundingClientRect().top;
  // console.log('브레이크 앵커와의 현재 거리 : ' + breakDistance);
  
  let stickyWrapHeight = document.querySelector('.sticky-wrap').getBoundingClientRect().height;
  let stickyWrapDistance = document.querySelector('.sticky-wrap').getBoundingClientRect().top;
  // console.log('스티키 외부와의 현재 거리 : ' + stickyWrapDistance);

  let stickyBox = document.querySelector('.sticky-box');
  let stickyBoxHeight = stickyBox.getBoundingClientRect().height;
  // console.log('스티키 박스의 높이 : ' + stickyBoxOffsetTop);

  if (stickyWrapDistance < 0 && breakDistance >= (stickyBoxHeight + PADDING)) {
    // 브레이크 지점에 도달하지 않았을때
    stickyBox.style.top = `${Math.abs(stickyWrapDistance) + PADDING}px`;
    
  } else if (breakDistance < (stickyBoxHeight + PADDING)) {
    // 브레이크 지점을 넘어섰을때
    stickyBox.style.top = `${stickyWrapHeight - stickyBoxHeight}px`;
    
  } else {
    // 다시 되돌아갔을때
    stickyBox.style.top = 0;
  }
})


/* 제이쿼리 사용할 경우 */
// $(window).on('scroll', function(){
//   const PADDING = 20; // 스티키 박스가 고정될 때 위아래 간격

//   let scrollTop = $(this).scrollTop();
//   // console.log('윈도우의 scrollTop : ' + scrollTop);

//   let breakOffsetTop = $('.break-anchor').offset().top;
//   // console.log('브레이크 앵커의 offsetTop : ' + breakOffsetTop);
  
//   let stickyWrapOffsetTop = $('.sticky-wrap').offset().top;
//   // console.log('스티키 외부의 offsetTop : ' + stickyWrapOffsetTop);

//   let stickyBox = $('.sticky-box');
//   let stickyBoxOffsetTop = stickyBox.height();
//   // console.log('스티키 박스의 높이 : ' + stickyBoxOffsetTop);

//   if (scrollTop > stickyWrapOffsetTop && (scrollTop + stickyBoxOffsetTop + PADDING) <= breakOffsetTop) {
//     // 브레이크 지점에 도달하지 않았을때
//     stickyBox.css('top', (scrollTop - stickyWrapOffsetTop + PADDING));
//   } else if ((scrollTop + stickyBoxOffsetTop + PADDING) > breakOffsetTop) {
//     // 브레이크 지점을 넘어섰을때
//     stickyBox.css('top', stickyBox.css('top', (breakOffsetTop - stickyBoxOffsetTop - stickyWrapOffsetTop)));
//   } else {
//     stickyBox.css('top', 0); // 다시 되돌아갔을때
//   }
// });