html 스크롤 시 Fixed 영역 만들기 + resize 이벤트 대응 방법

2024-01-15


사진: Unsplash 의 Jason Hudson


1. css

 

<style>
    .test_mother_container{
        max-width: 1000px;
        display: flex;
        width: 100%;
        align-items: flex-start;
        gap: 1.875rem;

        position: relative;
    }
    .test_text_child{
        display: flex;
        width : 200px;
        height : 200px;
    }
    .test_text_child_wrap{
        display: flex;
        width : 100%;
        height : 100px;
        color : white;
        background-color: purple;
    }
    .test_text_child_wrap.fixed{
        position:fixed; top:0;
    }

    .test_card_container{
        display: flex;

        width : 500px;
        height : 10000px;
        color : white;
        background-color: orange;
    }
</style>

2. html

 

<body>
<div class="test_mother_container" id="big_test_mother_container">
    <div class="test_text_child"  id="big_test_text_child">
        <div class="test_text_child_wrap" id="big_test_text_child_wrap">
            Fixd AREA long~~~~~~~~
        </div>
    </div>
    <div class="test_card_container">
        <div class="test_card_child_container">
            Main AREA
        </div>
    </div>
</div>
</body>

3. JavaScript

 

<script>
    document.addEventListener("DOMContentLoaded", function () {

        let nameKey = ['big'] //반응형일 경우 다른거 추가 가능

        // 브라우저 전체 스크롤 이벤트를 감지합니다.
        window.addEventListener('scroll', function () {

            for (let i = 0; i < nameKey.length; i++) {
                //고정시킬 영역과 계속 스크롤할 영역을 자식으로 가지는 태그 가져온다.
                const testMotherContainer = document.getElementById(`${nameKey[i]}_test_mother_container`);
                //고정시켜야할 태그의 현재 화면에서 상대적 상단 위치 + 현재 스크롤의 위치 = 고정시켜야할 태그 페이지 전체에서의 상단위치
                const testMotherContainerTop = testMotherContainer.getBoundingClientRect().top + window.scrollY;

                const testTextChildWrap = document.getElementById(`${nameKey[i]}_test_text_child_wrap`);
                const testTextChildWrapWidth = testTextChildWrap.offsetWidth;

                if (window.scrollY >= testMotherContainerTop) { //스크롤이 고정시켜야할 태그 페이지 전체에서의 상단위치를 지나치면 고정 속성 추가
                    testTextChildWrap.style.width = testTextChildWrapWidth + 'px';
                    testTextChildWrap.classList.add('fixed'); //고정 속성 부여
                } else {
                    testTextChildWrap.style.width = 'auto';
                    testTextChildWrap.classList.remove('fixed');
                }
            }
        });


        // Javascript
        window.addEventListener('resize', function () {
            for (let i = 0; i < nameKey.length; i++) {
                const testTextChild = document.getElementById(`${nameKey[i]}_test_text_child`);
                const testTextChildWidth = testTextChild.offsetWidth;
                const testTextTitleTop = testTextChild.getBoundingClientRect().top + window.scrollY;

                const testTextChildWrap = document.getElementById(`${nameKey[i]}_test_text_child_wrap`);

                testTextChildWrap.style.width = testTextChildWidth + 'px';

                if (window.scrollY >= testTextTitleTop) {
                    testTextChildWrap.classList.add('fixed');
                } else {
                    testTextChildWrap.classList.remove('fixed');
                }
            }
        });
    });
</script>

메인 이미지 출처 : 사진: UnsplashJason Hudson