JSFiddle - React, Tailwind, and code Playground

by uiwwnw

HTML

<div>
  <header class="header">
    헤더헤더
  </header>
</div>
<p>
  <span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Esse laboriosam porro iste a inventore nulla possimus consectetur beatae deserunt id ipsa natus omnis rerum at fugit sed, dolore odit ut.</span>
  <span>Iure nihil esse ratione non, aspernatur earum accusantium fuga laboriosam doloremque debitis eligendi blanditiis excepturi voluptate sapiente animi voluptatum placeat molestias pariatur? Laborum assumenda nemo laudantium nulla, explicabo repellat sunt.</span>
  <span>Hic, consectetur eius repudiandae asperiores animi corporis sapiente repellat id praesentium impedit ullam explicabo veritatis nesciunt! Vero vel quod unde ex et asperiores iusto eaque eum maiores consequuntur, accusantium quae.</span>
  <span>Debitis laborum quisquam, animi incidunt quis corporis, quo amet nesciunt ea ex deserunt vero impedit doloremque repudiandae, quidem, eos accusamus velit a sapiente. Porro asperiores voluptatibus doloremque commodi, voluptate sed.</span>
  <span>Sapiente fuga similique minima repellat nam omnis incidunt sunt explicabo quaerat soluta culpa dolorem, quisquam non impedit pariatur temporibus, saepe, magni accusantium doloribus nostrum, perferendis animi eum aspernatur alias! Deleniti!</span>
  <span>Tempora aspernatur temporibus, deleniti! Qui ratione minima blanditiis eaque nam quibusdam illo alias veniam. Magnam nesciunt deleniti, aperiam, vel aspernatur ducimus similique odit neque accusantium nam aliquid minus facere, ipsam!</span>
  <span>Dolorem quo rerum suscipit ipsa ducimus, cupiditate, debitis, nostrum adipisci eveniet sapiente corporis neque deserunt consequuntur reiciendis ut minus earum maiores reprehenderit officia? Deserunt, perferendis repellendus, velit nihil nam veritatis.</span>
  <span>Nemo id necessitatibus saepe unde suscipit expedita in quidem dignissimos! Unde omnis reiciendis odit beatae minus necessitatibus illo veritatis, animi. Quas impedit, maxime est dolorem...

CSS

.sticky {
  position: fixed;
  width: 100%;
  top: 0;
}

.stickyWrap * {
  background: #000;
  color: #fff;
}

.header {
  background: #fff;
}

JavaScript

var sticky = (function() {
  var stikyList = []; // 스티키 elem array
  var idx = 0; // index
  var exTop; // 스크롤 상하 체크를 위한 이전 스크롤 높이
  var direct; // 스크롤 방향
  var length = stikyList.length; // 스티키 elem.length
  var _push = function(e) { //  스티키 elem추가 fn
    (e.length !== 0) && (stikyList.push(e));
    length = stikyList.length;
  };
  var $elem; // elem;
  var $elemWrap; // elem.parent();
  var $elemTop; // elem.parent().offset().top;
  var $elemHeight; // elem.outerHeight();
  var $prevElemHeight; // prevElem.outerHeight();
  var $prevElemTop; // prevPrevElem.offset().top;
  var $scrollTop; // 윈도우 스크롤 위치
  var _chk = function(i) {
    if (i !== undefined) {
      idx = i;
    };
    $elem = stikyList[idx]; // 해당 index의 스티키 elem
    $elemWrap = $elem.parent();
    $elemTop = $elemWrap.offset().top;
    $elemHeight = $elem.outerHeight();
    $prevElemHeight = stikyList[idx - 1] === undefined ? 0 : stikyList[idx - 1].outerHeight();
    $prevElemTop = stikyList[idx - 1] === undefined ? 0 : Number(stikyList[idx - 1].css('margin-top').replace('px', ''));
  };
  var _act = function(i) {
    (i !== undefined) && (direct = true);
    if (($scrollTop > $elemTop) && direct) { // 스크롤이벤트가 하단일 경우
      (idx !== length - 1) && (idx++); // idx값을 높여 다음 스티키만 체크하도록
      (i !== undefined) && (idx = i);
      $elemWrap.css('padding-top', $elemHeight); // 스티키된 객체의 높이 부모에게 패딩값으로 주기
      $elem.addClass('sticky'); // elem에 스티키 클래스 추가
      $elem.css('margin-top', $prevElemHeight + $prevElemTop); // elem이 처음이 아닐경우, 마진으로 높이 맞춤
    } else if (($scrollTop < $elemTop) && !direct) { // 스크롤이벤트가 상단일 경우
      (idx !== 0) && (idx--); // idx값을 낮춰 이전 스티키만 체크하도록
      (i !== undefined) && (idx = i);
      $elemWrap.css('padding-top', ''); // 부모에게 주었던 높이 제거
      $elem.removeClass('sticky'); // 스티키 클래스 삭제
      $elem.css('margin-top', ''); // 마진값 제거
    }
  };
  $(window).on('scroll', function() {
    var $this = $(this); // $(window)
    _chk();
    _act();
    $scrollTop = $this.scrollTop() +...