강의

멘토링

커뮤니티

Cộng đồng Hỏi & Đáp của Inflearn

Hình ảnh hồ sơ của mario2139578
mario2139578

câu hỏi đã được viết

Bản sao tương tác trang web của Apple!

chi tiết ứng dụng main.js

강사님 질문있습니다.

Viết

·

316

0

main.add.js파일을 복붙해서 넣었는데 오류가 발생되어서 제 아무리 찾아봐도 어디서 오타인지를 못찾아서 도움을 요청하려고 글을 남깁니다.

오류는 콘솔로그에

Uncaught TypeError: Cannot read property 'style' of null

    at playAnimation (main.js:257)

    at scrollLoop (main.js:355)

    at main.js:361 라고 뜹니다.

제 스스로 찾아야하는데 도움부탁드립니다.

우선 제 js코드를 올려드리겠습니다.

(() => {
    let yOffset = 0; //window.pageYOffset 대신 쓸 변수
    let prevScrollHeight = 0; // 현재 스크롤 위치(yOffset)보다 이전에 위치한 스크롤 섹션들의 스크롤 높이값의 합
    let currentScene = 0; // 현재 활성화된(눈 앞에 보고있는) 씬(scroll-section)
    let enterNewScene = false; // 새로운 scene이 시작된 순간 true

    const sceneInfo = [{
            // 0
            type: 'sticky',
            heightNum: 5, // 브라우저 높이의 5배로 scrollHeight 세팅
            scrollHeight: 0,
            objs: {
                container: document.querySelector('#scroll-section-0'),
                messageA: document.querySelector('#scroll-section-0 .main-message.a'),
                messageB: document.querySelector('#scroll-section-0 .main-message.b'),
                messageC: document.querySelector('#scroll-section-0 .main-message.c'),
                messageD: document.querySelector('#scroll-section-0 .main-message.d')
            },
            values: {
                messageA_opacity_in: [0, 1, {
                    start: 0.1,
                    end: 0.2
                }],
                messageB_opacity_in: [0, 1, {
                    start: 0.3,
                    end: 0.4
                }],
                messageC_opacity_in: [0, 1, {
                    start: 0.5,
                    end: 0.6
                }],
                messageD_opacity_in: [0, 1, {
                    start: 0.7,
                    end: 0.8
                }],
                messageA_translateY_in: [20, 0, {
                    start: 0.1,
                    end: 0.2
                }],
                messageB_translateY_in: [20, 0, {
                    start: 0.3,
                    end: 0.4
                }],
                messageC_translateY_in: [20, 0, {
                    start: 0.5,
                    end: 0.6
                }],
                messageD_translateY_in: [20, 0, {
                    start: 0.7,
                    end: 0.8
                }],
                messageA_opacity_out: [1, 0, {
                    start: 0.25,
                    end: 0.3
                }],
                messageB_opacity_out: [1, 0, {
                    start: 0.45,
                    end: 0.5
                }],
                messageC_opacity_out: [1, 0, {
                    start: 0.65,
                    end: 0.7
                }],
                messageD_opacity_out: [1, 0, {
                    start: 0.85,
                    end: 0.9
                }],
                messageA_translateY_out: [0, -20, {
                    start: 0.25,
                    end: 0.3
                }],
                messageB_translateY_out: [0, -20, {
                    start: 0.45,
                    end: 0.5
                }],
                messageC_translateY_out: [0, -20, {
                    start: 0.65,
                    end: 0.7
                }],
                messageD_translateY_out: [0, -20, {
                    start: 0.85,
                    end: 0.9
                }]
            }
        },
        {
            // 1
            type: 'normal',
            // heightNum: 5, // type normal에서는 필요 없음
            scrollHeight: 0,
            objs: {
                container: document.querySelector('#scroll-section-1')
            }
        },
        {
            // 2
            type: 'sticky',
            heightNum: 5,
            scrollHeight: 0,
            objs: {
                container: document.querySelector('#scroll-section-2'),
                messageA: document.querySelector('#scroll-section-2 .a'),
                messageB: document.querySelector('#scroll-section-2 .b'),
                messageC: document.querySelector('#scroll-section-2 .c'),
                pinB: document.querySelector('#scroll-section-2 .b .pin'),
                pinC: document.querySelector('#scroll-section-2 .c .pin')
            },
            values: {
                messageA_translateY_in: [20, 0, {
                    start: 0.15,
                    end: 0.2
                }],
                messageB_translateY_in: [30, 0, {
                    start: 0.6,
                    end: 0.65
                }],
                messageC_translateY_in: [30, 0, {
                    start: 0.87,
                    end: 0.92
                }],
                messageA_opacity_in: [0, 1, {
                    start: 0.25,
                    end: 0.3
                }],
                messageB_opacity_in: [0, 1, {
                    start: 0.6,
                    end: 0.65
                }],
                messageC_opacity_in: [0, 1, {
                    start: 0.87,
                    end: 0.92
                }],
                messageA_translateY_out: [0, -20, {
                    start: 0.4,
                    end: 0.45
                }],
                messageB_translateY_out: [0, -20, {
                    start: 0.68,
                    end: 0.73
                }],
                messageC_translateY_out: [0, -20, {
                    start: 0.95,
                    end: 1
                }],
                messageA_opacity_out: [1, 0, {
                    start: 0.4,
                    end: 0.45
                }],
                messageB_opacity_out: [1, 0, {
                    start: 0.68,
                    end: 0.73
                }],
                messageC_opacity_out: [1, 0, {
                    start: 0.95,
                    end: 1
                }],
                pinB_scaleY: [0.5, 1, {
                    start: 0.6,
                    end: 0.65
                }],
                pinC_scaleY: [0.5, 1, {
                    start: 0.87,
                    end: 0.92
                }]
            }
        },
        {
            // 3
            type: 'sticky',
            heightNum: 5,
            scrollHeight: 0,
            objs: {
                container: document.querySelector('#scroll-section-3'),
                canvasCaption: document.querySelector('.canvas-caption')
            },
            values: {

            }
        }
    ];

    function setLayout() {
        // 각 스크롤 섹션의 높이 세팅
        for (let i = 0; i < sceneInfo.length; i++{
            if (sceneInfo[i].type === 'sticky'{
                sceneInfo[i].scrollHeight = sceneInfo[i].heightNum * window.innerHeight;
            } else if (sceneInfo[i].type === 'normal'{
                sceneInfo[i].scrollHeight = sceneInfo[i].objs.container
            }

            sceneInfo[i].objs.container.style.height = `${sceneInfo[i].scrollHeight}px`;
        }
        yOffset = window.pageYOffset;

        let totalScrollHeight = 0;

        for (let i = 0; i < sceneInfo.length; i++{
            totalScrollHeight += sceneInfo[i].scrollHeight;
            if (totalScrollHeight >= yOffset{
                currentScene = i;
                break;
            }
        }
        document.body.setAttribute('id', `show-scene-${currentScene}`);
    }

    function calcValues(values, currentYOffset) {
        let rv;
        //현재 씬(스크롤섹션)에서 스크롤된 범위를 비율로 구하기
        const scrollHeight = sceneInfo[currentScene].scrollHeight;
        const scrollRatio = currentYOffset / scrollHeight;

        if (values.length === 3{
            //start ~ end 사이에 애니메이션 실행
            const partScrollStart = values[2].start * scrollHeight;
            const partScrollEnd = values[2].end * scrollHeight;
            const partScrollHeight = partScrollEnd - partScrollStart;

            if (currentYOffset >= partScrollStart && currentYOffset <= partScrollEnd{
                rv = (currentYOffset - partScrollStart/ partScrollHeight * (values[1- values[0]) + values[0];
            } else if (currentYOffset < partScrollStart{
                rv = values[0];
            } else if (currentYOffset > partScrollEnd{
                rv = values[1];
            }

        } else {
            rv = scrollRatio * (values[1- values[0]) + values[0];
        }

        return rv;
    }


    function playAnimation() {

        const objs = sceneInfo[currentScene].objs;
        const values = sceneInfo[currentScene].values;
        const currentYOffset = yOffset - prevScrollHeight;
        const scrollHeight = sceneInfo[currentScene].scrollHeight;
        const scrollRatio = currentYOffset / scrollHeight;




        switch (currentScene{
            case 0:
                // console.log('0 play')


                if (scrollRatio <= 0.22{
                    // in
                    objs.messageA.style.opacity = calcValues(values.messageA_opacity_in, currentYOffset);
                    objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_in, currentYOffset)}%, 0)`;
                } else {
                    // out
                    objs.messageA.style.opacity = calcValues(values.messageA_opacity_out, currentYOffset);
                    objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_out, currentYOffset)}%, 0)`;
                }

                if (scrollRatio <= 0.42{
                    // in
                    objs.messageB.style.opacity = calcValues(values.messageB_opacity_in, currentYOffset);
                    objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_in, currentYOffset)}%, 0)`;
                } else {
                    // out
                    objs.messageB.style.opacity = calcValues(values.messageB_opacity_out, currentYOffset);
                    objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_out, currentYOffset)}%, 0)`;
                }

                if (scrollRatio <= 0.62{
                    // in
                    objs.messageC.style.opacity = calcValues(values.messageC_opacity_in, currentYOffset);
                    objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_in, currentYOffset)}%, 0)`;
                } else {
                    // out
                    objs.messageC.style.opacity = calcValues(values.messageC_opacity_out, currentYOffset);
                    objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_out, currentYOffset)}%, 0)`;
                }

                if (scrollRatio <= 0.82{
                    // in
                    objs.messageD.style.opacity = calcValues(values.messageD_opacity_in, currentYOffset);
                    objs.messageD.style.transform = `translate3d(0, ${calcValues(values.messageD_translateY_in, currentYOffset)}%, 0)`;
                } else {
                    // out
                    objs.messageD.style.opacity = calcValues(values.messageD_opacity_out, currentYOffset);
                    objs.messageD.style.transform = `translate3d(0, ${calcValues(values.messageD_translateY_out, currentYOffset)}%, 0)`;
                }




                break;
            case 2:
                // console.log('2 play');
                if (scrollRatio <= 0.32{
                    // in
                    objs.messageA.style.opacity = calcValues(values.messageA_opacity_in, currentYOffset);
                    objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_in, currentYOffset)}%, 0)`;
                } else {
                    // out
                    objs.messageA.style.opacity = calcValues(values.messageA_opacity_out, currentYOffset);
                    objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_out, currentYOffset)}%, 0)`;
                }

                if (scrollRatio <= 0.67{
                    // in
                    objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_in, currentYOffset)}%, 0)`;
                    objs.messageB.style.opacity = calcValues(values.messageB_opacity_in, currentYOffset);
                    objs.pinB.style.transform = `scaleY(${calcValues(values.pinB_scaleY, currentYOffset)})`;
                } else {
                    // out
                    objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_out, currentYOffset)}%, 0)`;
                    objs.messageB.style.opacity = calcValues(values.messageB_opacity_out, currentYOffset);
                    objs.pinB.style.transform = `scaleY(${calcValues(values.pinB_scaleY, currentYOffset)})`;
                }

                if (scrollRatio <= 0.93{
                    // in
                    objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_in, currentYOffset)}%, 0)`;
                    objs.messageC.style.opacity = calcValues(values.messageC_opacity_in, currentYOffset);
                    objs.pinC.style.transform = `scaleY(${calcValues(values.pinC_scaleY, currentYOffset)})`;
                } else {
                    // out
                    objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_out, currentYOffset)}%, 0)`;
                    objs.messageC.style.opacity = calcValues(values.messageC_opacity_out, currentYOffset);
                    objs.pinC.style.transform = `scaleY(${calcValues(values.pinC_scaleY, currentYOffset)})`;
                }

                break;

            case 3:
                // console.log('3 play');
                break;

        }
    }


    function scrollLoop() {
        enterNewScene = false;
        prevScrollHeight = 0;
        for (let i = 0; i < currentScene; i++{
            prevScrollHeight += sceneInfo[i].scrollHeight;
        }

        if (yOffset > prevScrollHeight + sceneInfo[currentScene].scrollHeight{
            enterNewScene = true;
            currentScene++;
            document.body.setAttribute('id', `show-scene-${currentScene}`);
        }

        if (yOffset < prevScrollHeight{
            if (currentScene === 0return // 브라우저 바운스 효과로 인해 마이너스가 되는 것을 방지(모바일)
            enterNewScene = true;
            currentScene--;
            document.body.setAttribute('id', `show-scene-${currentScene}`);
        }
        if (enterNewScenereturn;

        playAnimation();
    }


    window.addEventListener('scroll', () => {
        yOffset = window.pageYOffset;
        scrollLoop();
    });
    //window.addEventListener('DOMContentLoaded', setLayout);
    window.addEventListener('load', setLayout);
    window.addEventListener('resize', setLayout);

})();
인터랙티브-웹HTML/CSS웹 디자인svgjavascript클론코딩

Câu trả lời 3

0

studiomeal님의 프로필 이미지
studiomeal
Người chia sẻ kiến thức

html 페이지에 favicon 이미지가 없을 경우 나타날 수 있는 메시지인데요,
우리가 하는 개발과는 상관 없으므로 공부하실 때는 그냥 넘어가셔도 무방합니다^^
실제 서비스할 페이지에서는 파비콘을 넣어주시는게 좋겠지요~
(여기 인프런 사이트의 브라우저 탭 부분에 보이는 예쁜 나뭇잎아이콘, 그게 파비콘이랍니다)

0

mario213님의 프로필 이미지
mario213
Người đặt câu hỏi

강사님 답변해주셔서 정말 감사합니다! 공지사항 글도 확인하고서 다시 해보니 오류메세지는 출력이 안되네요!

그리고 또 다른 질문이 있습니다. 저장을 하고서 크롬으로 실행 시키면 가끔씩 favicon을 찾을수 없습니다?라는 문구가 뜨더라고요 

이거는 큰문제없으면 넘어가도 되는지 질문합니다

다시한번 답변해주셔서 너무 감사합니다 저기서 막혀서 진도를 못나갔었는데 이제 쫌 맘 편해지면서 더 공부할 마음이 생기네요

0

studiomeal님의 프로필 이미지
studiomeal
Người chia sẻ kiến thức

main-add.js에서 아래 부분에

container: document.querySelector('#scroll-section-1')

이렇게 content를 추가해 보시겠어요?
중간에 소스코드가 업데이트되면서 제가 빠뜨린 것 같습니다 죄송^^;
(덕분에 발견했어요 감사합니다!)
소스코드도 업데이트 해두었으니 그냥 다시 다운로드 받으시면 해당 부분이 추가되어 있을거에요.

container: document.querySelector('#scroll-section-1'),
content: document.querySelector('#scroll-section-1 .description')

그리고 setLayout 함수가 조금 덜 작성되어 있는 것 같아서,
아래 코드를 다시 넣어드릴게요.

function setLayout() {

        // 각 스크롤 섹션의 높이 세팅
		for (let i = 0; i < sceneInfo.length; i++) {
			if (sceneInfo[i].type === 'sticky') {
				sceneInfo[i].scrollHeight = sceneInfo[i].heightNum * window.innerHeight;
			} else if (sceneInfo[i].type === 'normal')  {
				sceneInfo[i].scrollHeight = sceneInfo[i].objs.content.offsetHeight + window.innerHeight * 0.5;
			}
            sceneInfo[i].objs.container.style.height = `${sceneInfo[i].scrollHeight}px`;
		}

        yOffset = window.pageYOffset;

        let totalScrollHeight = 0;

        for (let i = 0; i < sceneInfo.length; i++) {
            totalScrollHeight += sceneInfo[i].scrollHeight;
            if (totalScrollHeight >= yOffset) {
                currentScene = i;
                break;
            }
        }

        document.body.setAttribute('id', `show-scene-${currentScene}`);
    }

이렇게 고쳐보시고 잘 동작하는지 확인해 봐주세요^^

Hình ảnh hồ sơ của mario2139578
mario2139578

câu hỏi đã được viết

Đặt câu hỏi