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

category > IT/코딩 Javascript

무찌마 / 2021. 9. 28. / 댓글

Position Sticky Polyfill

2021.04.19 - [IT/코딩 Javascript] - Position Sticky를 구현하는 Fixed JS 코드 오류 수정

2021.06.10 - [IT/코딩 Javascript] - Position Sticky를 구현하는 Fixed JS 코드 2차 수정본

2021.06.13 - [IT/코딩 Javascript] - Position Sticky를 구현하는 Fixed JS 코드 3차 수정본

2021.10.05 - [IT/코딩 Javascript] - Position Sticky를 구현하는 Fixed JS 코드 활용


 

4차 수정 코드

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

 

변경 사항

 

변경 전(3차 코드)

nav.parentNode.appendChild(tmp);

 

변경 후(4차 코드)

nav.parentNode.insertBefore(tmp, nav.nextSibling);

 

변경 이유

 

DOM 객체 nav를 복제한 tmp를 sibling 객체로 붙이는 것이 이 코드의 목적입니다.

nav + tmp의 순서가 되어야 합니다.

 

1. 예제-1

<div>(nav의 parent)

nav

tmp가 들어가는 위치

</div>

 

2. 예제-2

<body>(nav의 parent)

nav

element-1

element-2

element-3

tmp가 들어가는 위치

</body>

 

appendChild()를 사용했을 경우 "예제-1"에서는 tmp 객체가 정상적인 원하는 위치에 들어갑니다.

 

"예제-2"에서는 tmp가 nav와 분리되어 엉뚱한 위치에 들어가므로 fixed position으로 설정한 nav가 콘텐츠의 흐름에서 빠져나간 빈 공간을 메우지 못하게 됩니다.

 

그래서 insertBefore()를 사용하여 강제로 tmp를 nav 다음 위치(sibling)에 집어넣었습니다. nav의 parent로 <div> 블록을 사용할 필요가 없게 되는 것입니다.

 

차라리 <div> 블록을 한 개 더 추가하는 것이 나을지 아니면 빼는 것이 로딩 속도나 메모리 가용성 면에서 유리할지 측정 자료가 없어서 모르겠습니다. 코드 연습하면서 알아 두면 유익한 내용이라 생각하여 그냥 등록합니다.


position sticky 사용하면 간단합니다. 그런데 해결 안 된 버그가 있어서 웹브라우저 및 CSS의 호환성 문제가 불규칙하게 발생합니다. sticky로 교체하고 테스트하면 flexbox와 충돌하여 코드를 여기저기 수정해야 하고 element 가운데로 설정하는 것도 조건에 따라서 오류가 발생합니다.

댓글