본문 바로가기

Issues/Javascript&jQuery

[javascript] 페이지 진입 시 새로고침인지 뒤로가기인지 확인하기! (window.performance.navigation.type == 1)

이슈

개발에서 데이터를 6개씩 끊어서 줘야하는데 최대 개수가 12개라서 api에서 페이징 처리없이 한번에 12개 상품을 주고, 더보기 페이징 처리를 display:none/block으로 처리해야했다.

그런데 기본 동작할때는 이슈가 없었는데, history back 할때 스크롤값과 기존에 더보기 했던 상품인데 더보기가 열려있지 않는 등 추가 이슈가 생겼다. 따라서 history관련 추가 작업이 필요했다.
==> history.state / history.replaceState()

그리고 현재 페이지 진입 동작이 새로고침이냐 뒤로가기냐에 따라서 다른 동작을 실행했어야했다.
==> window.performance.navigaion.type === 1

 

해결

if (window.performance.navigation.type == 1) {
    // 새로고침시에 history.state 리셋
}

 


작업한 소스 상세

 


1. history object

const loadHistory = history.state;

/** history data */
const historyObj = {
    recommend: {
        isMore: loadHistory && loadHistory.recommend ? !!loadHistory.recommend.isMore : false,
        lastTab: null,
    },
    best: {
        isMore: loadHistory && loadHistory.best ? !!loadHistory.best.isMore : false,
        lastTab: null,
    },
    price: {
        isMore: loadHistory && loadHistory.price ? !!loadHistory.price.isMore : false,
        lastTab: null,
    },
    scroll: loadHistory && loadHistory.scroll ? loadHistory.scroll : 0
};

 


2. history.state에 저장하기(세팅하기) (window.history.replaceState())

/** set history data */
function setHistoryMores (key, type, data = true) {
    const _history = { ...historyObj };
    
    if (type) {
        _history[key][type] = data;
    }
    else {
        _history[key] = data;
    }

    history.replaceState(Object.assign({}, history.state, _history), '')
};

 


3. history.state에 저장된 값 가져오기

/** get history data */
function getHistoryMores (key, type) {
    const _state = history.state;
    if (_state === null) return ;

    if (type) return _state[key][type];
    else return _state[key];
};

 


4. 새로고침시에 history.state 리셋하기

/** reset history */
function resetHistoryState () {
    window.history.replaceState(null, '');
}

/** 새로고침 시에만 실행 (history back인 경우 x) */
if (window.performance.navigation.type == 1) {
    resetHistoryState();
}

 


5. history가 있으면 ? ===> historyback이면 스크롤 위치값 변경 / 더보기 클릭한 경우에 아이템모두 show

/** 스크롤 위치 변경 */
function getHistoryScroll () {
    if( getHistoryMores('scroll') && isFromBack ) {
        window.scrollTo(0, getHistoryMores('scroll'))
    };
};
/** 아이템 세팅 (6개씩 보여줌) */
function handleSetItems(key) {
    const $items = $(`.js__${key}__list`);

    if ($items.length) {
        if (getHistoryMores(key, 'isMore') && isFromBack) {
            $items.addClass('show');
        }
        else {
            $items.each(function(index, element) {
                if(index < 6) $(element).addClass("show");
            })
        }
    }

    getHistoryScroll();
}
뒤로가기 했는데 이전에 더보기 클릭했던 경우 ==> 아이템 모두 show
처음오는거고 더보기 클릭하지 않았을 경우 ==> 6개만 보여주기

 


6. 더보기버튼 눌렀을 경우 history 세팅하기

/** 아이템 더보기 show */
function handleMoreItems( $items, { visibles, key, url } ) {
    if ( !$items.length || !visibles || !url ) return;

    const _rowCount = 6;

    if ( visibles == _rowCount ) {
        setHistoryMores(key, 'isMore', true); //history 관리
        $items.addClass("show"); //남은 아이템 show
    }
    else {
        setHistoryMores('scroll', null, window.scrollY) //새페이지 이동 시 스크롤 값 저장
        window.location.href = url; //새페이지 이동
    }
};


/** 더보기 버튼 이벤트 */
function moreEvent () {
    $(document).on("click", ".js__promo__more", function () {
        const key = $(this).data("keyword"); //recommend, best, price

        const $items = $(`.js__${key}__list`);
        const $visibleItems = $(`.js__${key}__list.show`);
        const url = devEventPromoNewSchool[`${key}Link`];

        handleMoreItems($items, {
            visibles: $visibleItems.length,
            key,
            url
        });
    })
}

 

반응형