2018년 2월 25일 일요일

[javascript]localstorage 를 이용한 쇼핑몰 내가본 상품 처리.

내가본 상품

요구사항

1.로그인이 필요 없이 동작.
2.상시노출 되는 레이어에 표시.
3.최근본 상품이 우선적으로 노출됨.
4.특정개수 이상이 될경우 오래된 상품 목록을 삭제.
5.상품을 본 시간 이후로 일정시간이 경과 되면 자동으로 삭제.
6.이미 저장된 상품은 추가되지 않는다.

위 요구 사항과 관련하여 개발할때 디비를 사용하거나, 쿠키를 보통 많이 사용하는데

난 로컬스토리지를 이용하여 개발 해봤다.

장점
1.보안상 안전 (쿠키데이터를 잘못사용할경우 보안에 취약할수 있을)
2.디비조회를 하지않으므로 부하가 적음

단점
1.저장공간의 물리적 제약이 있음(브라우저별 상이)

필요한 상수 값

//최근본 아이템 삭제 기간
var LATELY_VIEW_ITEM_EXPIRATION_DATE = 1;
//최근본 아이템 최대 저장 개수
var LATELY_VIEW_ITEM_MAX_SAVE_COUNT = 50;
//최근본 아이템 페이징 사이즈
var LATELY_VIEW_ITEM_PAGEING_SIZE = 5;

필요한 함수
/**
 * 
 * @param obj
 * @returns
 */
function isNull(obj){
if(obj == '' || obj == null || obj == undefined || obj == NaN){ 
return true;
}else{
return false;
}
}

/**
 * 로컬스토리지 저장
 * @param name
 * @param obj
 * @returns
 */
function setLocalStorage(name,obj){
localStorage.setItem(name, obj);
}

/**
 * 로컬 스토리지 삭제
 * @param name
 * @returns
 */
function removeLocalStorage(name){
localStorage.removeItem(name);
}

/**
 * 로컬스토리지에서 특정 객체 가져오기
 * @param name
 * @returns
 */
function getItemLocalStorage(name){
return localStorage.getItem(name);
}

준비가 되었으면


1.모든 페이지에서 수행되야 하므로 common.js document.ready() 함수내에 정의한다.


$(document).ready(function(){
initLatelyViewItemList();




2.initLatelyViewItemList() 함수를 정의한다. 

/**
 * 최근 본 상품 관련 로컬 스토리지 공간 확보 일정 시간 지난 것 뺴고 재저장 페이지별 무조건 호출
 * @returns
 */
function initLatelyViewItemList(){
        //로컬스토리지에서 latelyViewItemList 로 저장된 정보가 있는지 확인후
if(isNull(getItemLocalStorage('latelyViewItemList'))){

                //없을경우 공간 생성
setLocalStorage('latelyViewItemList',null);

                //상품을 표시할 ul에 없을경우 화면 표시
$("ul#latelyViewItemList_ul").append('<li>찾아본<br>상품이<br>없습니다.                    </li>');
        //기존 정보가 있을 경우
}else{
                저장된 정보를 가져오고
var latelyViewItemListJson = getItemLocalStorage('latelyViewItemList');
                //실제 저장된 데이터가 있는경우 
if(latelyViewItemListJson != "null" || isNull(latelyViewItemListJson)){
var nowDate = new Date();
//문자열을 javascript 객체로 변환
var latelyViewItemList = JSON.parse(latelyViewItemListJson);

                        //일정시간 경과된 아이템을 제외하고 다시 넣기 위한 새로운 Array
var latelyViewItemListNew = new Array();
                        //상품 리스트를 돌면서 상품별 저장된 시간이 현재 시간보다 클경우만
                        //다시 latelyViewItemListNew  에 추가
for(var i in latelyViewItemList){
var viewTime = new Date(latelyViewItemList[i].viewTime);
//시간이 경과된경우 를 제외하고 재 저장
if(nowDate.getTime() < viewTime.getTime()){
latelyViewItemListNew.push(latelyViewItemList[i]);
}
}
//시간이 모두 경과된 경우 담긴 새로운 배열요소가 없으므로 로컬 스토                          //리지를 비워줌.
if(latelyViewItemListNew.length == 0){
setLocalStorage('latelyViewItemList',null);
                        //재저장
}else{
setLocalStorage('latelyViewItemList',JSON.stringify(latelyViewItem                                ListNew));
}
}
                //화면 을 그리는 함수호출
LatelyViewItemRender(1);
}
}

3.상품을 보기시 호출될 moveItemViewPage() 정의

화면단에 아래체럼 상품링크를 구성한다.

<a href="#" onclick="javascript:moveItemViewPage('상품번호 ','상품이미지경로'); return false;">


/**
 * 로컬 스토리지 저장 후 아이템 상세보기 페이지 이동
 * @param itemSeq
 * @returns
 */
function moveItemViewPage(itemSeq,itemImagePath){
var latelyViewItemListJson = getItemLocalStorage('latelyViewItemList');
var viewTime = new Date();
//최근 본 상품이 아얘 없을경우 무조건 저장
if(latelyViewItemListJson == "null" || isNull(latelyViewItemListJson)){

                //사로 저장될 
var latelyViewItemListNew = new Array();
var latelyViewItem = {
"itemSeq" : itemSeq
,"itemImagePath" : itemImagePath
,"viewTime" :viewTime.setDate(viewTime.getDate() + Number(LATELY_VIEW_ITEM_EXPIRATION_DATE))
}
latelyViewItemListNew.unshift(latelyViewItem);
setLocalStorage('latelyViewItemList',JSON.stringify(latelyViewItemListNew));
//있을경우 
}else{
var latelyViewItemList = JSON.parse(latelyViewItemListJson);
var isExistsItem = false;

breakPoint : for(var i in latelyViewItemList){
if(Number(latelyViewItemList[i].itemSeq) == Number(itemSeq)){
isExistsItem = true; 
break breakPoint;
}
}
//새로본 상품일경우만 저장
if(!isExistsItem){
//최대 50개 일경우 마지막꺼 삭제 후제일 앞에 저장
if(latelyViewItemList.length == Number(LATELY_VIEW_ITEM_MAX_SAVE_COUNT)) latelyViewItemList.pop();
var latelyViewItem = {
"itemSeq" : itemSeq
,"itemImagePath" : itemImagePath
,"viewTime" :viewTime.setDate(viewTime.getDate() + Number(LATELY_VIEW_ITEM_EXPIRATION_DATE))
}
latelyViewItemList.unshift(latelyViewItem);
setLocalStorage('latelyViewItemList',JSON.stringify(latelyViewItemList));
}
}

        //상품페이지로 이동
location.href="/item/itemView.do?item_seq=" + itemSeq;
}





4.LatelyViewItemRender() 함수를 정의한다. 
(html 선택자는 각각 다를수 있으므로 참조만 하자.)

/**
 * 최근 본 상품 화면 셋팅(페이징)
 * @param list
 * @returns
 */
function LatelyViewItemRender(page){
        //기본적으로 일단 상품리스트를 비움
$("ul#latelyViewItemList_ul").empty();
        //로컬스토리지에서 latelyViewItemList 값 확인
if(getItemLocalStorage('latelyViewItemList') != "null" || isNull(getItemLocalStorage('latelyViewItemList'))){
var latelyViewItemList = JSON.parse(getItemLocalStorage('latelyViewItemList'));

                //페이징을 해야하기때문에 전체 개수가 필요함
var length = latelyViewItemList.length;
                
                //최대 나올수 있는 페이지를 셋팅.
var maxPage = length / LATELY_VIEW_ITEM_PAGEING_SIZE;

                //페이징 처리부분 레이어 노출시킴
$("div#latelyViewItemListPageing_div").css("display","block");

                //함수호출시 전달받은 페이지 값으로 현재페이지 셋팅.
$("strong#nowLatelyViewItemPage_strong").text(page);

                //최대 페이지 개수 셋팅
$("span#totalLatelyViewItemPage_span").text(Math.ceil(maxPage))

//가져온 최근본상품리스트에서 노출해야할 인덱스을 구해서 노출
for(var i = ((page-1) * LATELY_VIEW_ITEM_PAGEING_SIZE); i < (page*LATELY_VIEW_ITEM_PAGEING_SIZE); i++){
                        
if(!isNull(latelyViewItemList[i])){
                                //상품 그리는 부분
$("ul#latelyViewItemList_ul").append(
$("<li>").append(
$("<a>").attr("href","/item/itemView.do?item_seq="+latelyViewItemList[i].itemSeq)
.append($("<img>").attr("src",latelyViewItemList[i].itemImagePath)
  .attr("alt","최근본상품"))));
}
}
}else{
                //상품이 없을경우
$("ul#latelyViewItemList_ul").append('<li>찾아본<br>상품이<br>없습니다.</li>');
$("div#latelyViewItemListPageing_div").css("display","none");
}
}

/**
 * 최근 본 상품 페이지 버튼 클릭
 * @param type
 * @returns
 */
function latelyViewItemPageingPlusMinus(type){
if(type == "minus"){
if(Number($("strong#nowLatelyViewItemPage_strong").text()) > 1){
$("strong#nowLatelyViewItemPage_strong").text(Number($("strong#nowLatelyViewItemPage_strong").text()) - 1);
LatelyViewItemRender($("strong#nowLatelyViewItemPage_strong").text());
}
}else{
if(Number($("strong#nowLatelyViewItemPage_strong").text()) < Number($("span#totalLatelyViewItemPage_span").text())){
$("strong#nowLatelyViewItemPage_strong").text(Number($("strong#nowLatelyViewItemPage_strong").text()) + 1);
LatelyViewItemRender($("strong#nowLatelyViewItemPage_strong").text());
}
}
}

프로세스를 좀 살펴 보자면 

화면에는 페이징 처리 레이어  예( 1/7 ) 같은 레이어가 있고 상품리스트를 표시할 ul태그가 존재한다.

기본 페이지이동시 매번 initLatelyViewItemList() 함수가 호출되어 로컬 스토리지에 최근본상품리스트에서 일정시간 지난 상품은 삭제후 재정한후 LatelyViewItemRender(1); 를 호출하여 1페이지상품을 로드 한다.

LatelyViewItemRender 함수는 전달받은 페이징 값에 위치하는 상품을 화면에 노출시키고 페이징 버튼을 다시 그린다.


좀 복잡할수 있는 내용이지만 페이징 알고리즘에 대한 개념만 확실히 알고있다면 이해할수 있는 내용이다.ㅎ











댓글 3개:

  1. 정말감사합ㄴㅣ다 ;0; 덕분에 한건해결했어요!!

    답글삭제
  2. 실례가 안된다면 제 블로그에 출처남기고 퍼가도 될까요??

    답글삭제

[lunux]리눅스 폴더별 용량 확인

리눅스 폴더별 용량 확인 조회 하고자 하는 디렉토리 리스트가있는 경로로 이동후 du -h --max-depth=1