Position Sticky를 구현하는 Fixed JS 코드 3차 수정본

카테고리 IT/코딩 Javascript

무찌마, 댓글

초고 2021. 6. 13.

Sticky Effect Polyfill 코드

 

1. 원글: Position Sticky를 구현하는 Fixed JS 코드 오류 수정

2. 수정: Position Sticky를 구현하는 Fixed JS 코드 2차 수정본

3. 수정: 본문

4. 수정: Position Sticky를 구현하는 Fixed JS 코드 4차 수정본

5. 활용: Position Sticky를 구현하는 Fixed JS 코드 활용

 

2, 3차 수정 코드 비교하고 간단한 설명 덧붙입니다.

 

※ The HTMLElement.offsetTop read-only property returns the distance of the outer border of the current element relative to the inner border of the top of the offsetParent, the closest positioned ancestor element.

출처: MDN, mdn web docs, "HTMLElement.offsetTop"

 

offsetTop은 현재 객체(요소)의 top border 바깥 면으로부터 offsetParent 객체의 top border 안쪽 면(inner)까지의  거리 값을 리턴합니다.

 


2차 수정 코드

const nav = document.getElementById('main-header'),
	tmp = nav.cloneNode(true),
	rectTop = nav.offsetTop;
tmp.style.visibility = 'hidden';
window.addEventListener('scroll', function() {
	if ( window.pageYOffset > rectTop && !tmp.parentNode ) {
		nav.parentNode.appendChild(tmp);
		nav.className = "fixed";
	} else if ( window.pageYOffset < rectTop && tmp.parentNode ) {
		tmp.parentNode.removeChild(tmp);
		nav.className = "static";
	}
});

 

3차 수정 코드

const nav = document.getElementById('main-header'),
	tmp = nav.cloneNode(false),
	rectTop = nav.offsetTop;
tmp.id = 'main-tmp';
window.addEventListener('scroll', function() {
	if ( window.pageYOffset > rectTop && !tmp.parentNode ) {
		nav.parentNode.appendChild(tmp);
		nav.className = "fixed";
	} else if ( window.pageYOffset < rectTop && tmp.parentNode ) {
		tmp.parentNode.removeChild(tmp);
		nav.className = "static";
	}
});

 

코드를 2, 3차 수정하면서 변경한 부분

 

1. cloneNode(deep) 의 옵션을 true에서 false로 변경

false 옵션을 사용하여 객체 nav를 복제하면 블록 내부의 내용은 복사하지 않습니다.

 

tmp = nav.cloneNode(false); [변경]

 

2. 원본 블록의 id 변경

HTML 문서에 1개만 존재해야 하는 id가 복제 블록 때문에 id가 중복 사용되었습니다.

복제 블록 tmp의 id를 'main-tmp'로 변경하는 구문입니다.

 

tmp.id = 'main-tmp'; [추가]

 

3-1. CSS 파일(style.css) 안에 id 'main-tmp' 관련 설정 추가하는 방법(선택-1)

복제 블록 tmp의 id가 'main-header'에서 'main-tmp'로 변경되었기 때문에 'main-header'의 CSS 설정을 공유하지 못하므로 'main-tmp'에 대한 설정 구문을 추가하는 것입니다. 자신의 환경에 맞게 변경합니다.

 

CSS 예문

#main-tmp {
	position: static;
	height: 80px;
	width: 100%;
}

 

3-2. "3-1"과 같이 CSS 파일 수정하지 않고 JS 파일에 라인 하나를 추가하는 방법(선택-2)

아래 예문은 JS 코드에 라인 하나를 추가한 것입니다. Style 요소를 추가하여 HTML로 출력하는 것입니다. 

※ 3차 수정 코드와 비교

※ 20210801 내용 수정

아래 구문에서 'rectTop'을 'nav.offsetHeight'로 수정하였습니다.

rectTop('nav.offseTop')은 element의 높이가 아니라 parent 객체의 상단으로부터 child 객체('nav')의 상단까지의 거리입니다.

 

tmp.id = 'main-tmp';
[추가] tmp.setAttribute('style', 'width:100%;height:' + nav.offsetHeight + 'px;');
window.addEventListener('scroll', function() {

 

4. truefalse로 변경했으므로 'tmp' 객체에 숨김 속성을 지정할 필요가 없습니다. 1, 2, 3은 반드시 적용해야 하지만, 4는 개인적으로 유용하게 사용할 수 있는 선택 조건입니다.

 

tmp.style.visibility = 'hidden'; [삭제]

코드 원본 개발자 링크

1. 티스토리 "Moon의 개발 일기"

소스 페이지: Javascript(jQuery) - position sticky IE polyfill(폴리필) 방법

2. Level Up Coding by gitconnected.com

How to Make Position Sticky Work in IE: Build Your Own CSS Polyfill with JavaScript


'cloneNode()' method에 대한 설명은 링크 참고

 

"Node.cloneNode() - Web APIs | MDN (mozilla.org)"

"HTML DOM cloneNode Method (w3schools.com)"

댓글