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() +...