본문 바로가기
웹 코딩/티스토리

Odyssey 오디세이 스킨 - 사이드 바 고정

by 알릭2 2020. 9. 16.

코드 재활용 및 저장 차원에서....

 

혹시 나중에 나도 스킨을 바꿀지 모르니까....

 

오디세이 스킨에서도 사이바 고정을 원한다면...

 

 

1. 스르륵 따라오는 버전

@media screen and (max-width:1060px) {
  aside.area-aside {
    margin-top: 0 !important;
  }
}
.main { align-items: flex-start; }
aside.area-aside {
  transition: margin-top 0.5s ease-in-out 0s, right .5s;
}
//// 아래 offset 함수는 퀵점프에 이용된 함수라, 이미 html상 존재한다면 삭제해도 됨
function offset(el) {
  var rect = el.getBoundingClientRect(),
    scrollLeft = window.pageXOffset || document.documentElement.scrollLeft,
    scrollTop = window.pageYOffset || document.documentElement.scrollTop;
  return { top: rect.top + scrollTop, left: rect.left + scrollLeft }
}
////
(function() {
  var lastScrollTop = 0;
  var article = document.querySelector(".area-main"); //본문영역 id
  var aside = document.querySelector(".area-aside"); //사이드바 id
  var initT = parseInt(window.getComputedStyle(aside, null).marginTop);
  if (document.documentElement.clientWidth > 1060 && article.offsetHeight > aside.offsetHeight) {
    window.addEventListener("scroll", function() {
      var scrT = window.pageYOffset || document.documentElement.scrollTop;
      var winH = document.documentElement.clientHeight;
      var sideH = aside.offsetHeight;
      var dir = (scrT > lastScrollTop) ? "down" : "up"; lastScrollTop = scrT;
      var sideT = offset(aside).top;
      var topLine = offset(article).top + initT;
      var bottomLine = topLine + article.offsetHeight - winH;
      
      if (sideH > winH) {
        if (dir == "down") {
          if (scrT >= (sideT + sideH - winH) && scrT < bottomLine) {
            aside.style.marginTop = scrT - topLine - (sideH - winH) + 'px';
          }
          if (scrT >= bottomLine) {
            aside.style.marginTop = Math.max(article.offsetHeight - sideH - topLine, 0) + 'px';
          }
        } else {
          if (scrT <= sideT && scrT > topLine) {
            aside.style.marginTop = scrT - topLine + 'px';
          }
          if (scrT <= topLine) {
            aside.style.marginTop = initT + 'px';
          }
        }
      } else {
        bottomLine = topLine + article.offsetHeight - sideH;
        if (dir == "down") {
          if (scrT > topLine && scrT < bottomLine) {
            aside.style.marginTop = scrT - topLine + initT + 'px';
          }
          if (scrT >= bottomLine) {
            aside.style.marginTop = bottomLine - topLine + 'px';
          }
        } else {
          if (scrT > topLine && scrT < bottomLine) {
            aside.style.marginTop = scrT - topLine + initT + 'px';
          }
          if (scrT <= topLine) {
            aside.style.marginTop = initT + 'px';
          }
        }
      }
    });
  }
})();

 

2. 찰싹! 붙는 버전

@media screen and (max-width:1059px) {
	aside.area-aside {
		position: fixed !important;
		top: 0 !important;
		right: -100% !important;
	}
	.area-aside.area-aside-on {
		right: 0 !important;
	}  
}
.main { 
	align-items: flex-start; 
}
//// 아래 offset 함수는 퀵점프에 이용된 함수라, 이미 html상 존재한다면 삭제해도 됨
function offset(el) {
  var rect = el.getBoundingClientRect(),
    scrollLeft = window.pageXOffset || document.documentElement.scrollLeft,
    scrollTop = window.pageYOffset || document.documentElement.scrollTop;
  return { top: rect.top + scrollTop, left: rect.left + scrollLeft }
}
////

var sidebarSticked = false;
stickySidebar();
window.addEventListener("resize", stickySidebar);
window.addEventListener("orientationChange", stickySidebar);

function stickySidebar() {
  var aside = document.querySelector(".area-aside");
  var article = document.querySelector(".area-main");
  var winW = document.documentElement.clientWidth;
  if (winW > 1059 && article.offsetHeight > aside.offsetHeight) {
    var parentWidth = aside.parentNode.offsetWidth - parseInt(window.getComputedStyle(aside.parentNode, null).paddingLeft) - parseInt(window.getComputedStyle(aside.parentNode, null).paddingRight);
    aside.style.right = (winW - parentWidth)/2 + 'px';
    aside.style.position = "absolute";
	aside.style.top = "unset";
	aside.style.bottom = "unset";
    if (!sidebarSticked) {
      sidebarSticked = true;
      var lastScrollTop = 0;
      window.addEventListener("scroll", function() {
        if (document.documentElement.clientWidth < 1060 && article.offsetHeight < aside.offsetHeight) { return; }
        var scrT = window.pageYOffset || document.documentElement.scrollTop;
        var winH = document.documentElement.clientHeight;
        var sideH = aside.offsetHeight;
        var dir = (scrT > lastScrollTop) ? "down" : "up";
        lastScrollTop = scrT;
        var sideT = offset(aside).top;
        var topLine = offset(article).top;
        var bottomLine = topLine + article.offsetHeight - winH;
        if (sideH > winH) {
          if (dir == "down") {
            if (scrT >= (sideT - winH + sideH) && scrT < bottomLine && aside.style.position != 'fixed') {
              aside.style.top = 'unset';
              aside.style.bottom = 0;
              aside.style.position = 'fixed';
            }
            if (scrT >= bottomLine && aside.style.position == 'fixed') {
              aside.style.top = 'unset';
              aside.style.bottom = 0;
              aside.style.position = 'absolute';
            }
            if (scrT < bottomLine && aside.style.top == '0px' && aside.style.position == 'fixed') {
              aside.style.top = sideT - topLine + aside.parentNode.offsetTop + 'px';
              aside.style.bottom = 'unset';
              aside.style.position = 'absolute';
            }
          } else {
            if (scrT <= sideT && scrT > topLine && aside.style.position != 'fixed') {
              aside.style.top = 0;
              aside.style.bottom = 'unset';
              aside.style.position = 'fixed';
            }
            if (scrT <= topLine && aside.style.position == 'fixed') {
              aside.style.top = 'unset';
              aside.style.bottom = 'unset';
              aside.style.position = 'absolute';
            }
            if (scrT > topLine && aside.style.bottom == '0px' && aside.style.position == 'fixed') {
              aside.style.top = sideT - topLine + aside.parentNode.offsetTop + 'px';
              aside.style.bottom = 'unset';
              aside.style.position = 'absolute';
            }
          }
        } else {
          bottomLine = topLine + article.offsetHeight - sideH;
          if (dir == "down") {
            if (scrT >= topLine && scrT < bottomLine && aside.style.position != 'fixed') {
              aside.style.top = 0;
              aside.style.position = 'fixed';
            }
            if (scrT >= bottomLine && aside.style.position == 'fixed') {
              aside.style.top = 'unset';
              aside.style.bottom = 0;
              aside.style.position = 'absolute';
            }
          } else {
            if (scrT >= topLine && scrT < bottomLine && aside.style.position != 'fixed') {
              aside.style.bottom = 'unset';
              aside.style.top = 0;
              aside.style.position = 'fixed';
            }
            if (scrT <= topLine && aside.style.position == 'fixed') {
              aside.style.top = 'unset';
              aside.style.position = 'absolute';
            }
          }
        }
      });
    }
  }
}

각각 일반적인 html 편집 방법으로 스타일과 스크립트 적용!

 

관련 글!!

2020/09/11 - [웹 코딩/티스토리] - 사이드 바 - 스크롤 따라 다니게 만들기

댓글