이슈
개발에서 데이터를 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
});
})
}
반응형
'Issues > Javascript&jQuery' 카테고리의 다른 글
[javascript] overloading 과 overriding (0) | 2021.12.29 |
---|---|
[javascript] es5환경에서 객체 반복 돌리기 (0) | 2021.12.29 |
[html & javascript] 가상요소 이벤트 바인딩 (template 태그) (0) | 2021.12.29 |
[javascript & html] 라디오 input 클릭했을때 확인 후 안되게 하기 (0) | 2021.12.29 |
[javascript & vue & scss ] 파일경로 ~ 와 @ (0) | 2021.12.29 |