[Vanilla JS] 쇼핑몰 인기검색어 롤링, 자동완성

Kyle·2021년 3월 13일
2

project

목록 보기
5/13
post-thumbnail

쇼핑하우

깃허브링크

개발 기간: 03/08 ~ 03/12

구현한 기능

  • 인기검색어 데이터 받아와서 rolling

  • 검색창 클릭 시 인기검색어 보여주기

  • 자동완성

    • 자동완성
    • 검색어 red-point처리
    • 키보드로 자동완성 값 조절
    • 디바운싱

실행화면

  • 인기검색어 롤링 및 클릭시 인기검색어

  • 자동완성

롤링

지난번에 구현했던 캐로셀과 비슷하게 구현했다. 넘어가는 범위는 overflow:hidden을 적용해주고 transformsetTimeout을 이용해서 일정 시간마다 반복하게 구현했다. 롤링을 하면서 마주쳤던 문제 중 기억에 남는 문제가 있어서 코드와 함께 작성한다.

아래에 나오는 코드는 문제를 해결한 코드이다. 일정 시간마다 자동으로 rolling 해주는 메소드이다.

  • render: transition을 없애고 위치를 0으로 변경시키고 렌더링한다.
  • rolling: transition을 설정하고 위치(y축)를 움직여준다.
  • delay(value,time): Promise를 반환하는 객체로 timems 뒤에 resolve(value)한다. 사이에 텀을 두기 위해 사용한 함수
async autoRolling() {
    if (this.step > this.rollingData.length) {
      this.render();
      this.step = 0;
      await delay('', 0);
      this.rolling();
      this.autoRolling();
    } else {
      setTimeout(() => {
        this.rolling();
        this.autoRolling();
      }, 3000);
    }
  }

문제

처음에는 위에 코드에 await delay('', 0);이 없었다. 하지만 중간에 조금의 delay를 주지않고 this.render();this.rolling(); 가 연달아서 진행된다. 즉 transitiontransform이 설정되는 과정만 본다면 아래와 같이 된다.

//render
this.rollingList.style.transition = none
this.rollingList.style.transform = `translateY(0px)`;
//rolling
this.rollingList.style.transition = 'all 1s';
this.rollingList.style.transform = `translateY(OOpx)`;
  • 해결

render이 설정한 this.rollingList.style는 rolling때문에 다 사라지게 된다. 나는 render이 실행된 후에 rolling이 실행되기 바랬기 때문에 사이에 await delay('', 0);를 두어 두 함수가 모두 실행될 수 있게 만들었다.

자동완성

amazon에서 데이터를 받아와서 자동완성을 구현했다. amazon의 자동완성의 Access-Control-Allow-Origin가 모두에게 허용하기 때문에 CORS문제 없이 사용할 수 있었다.

자동완성 하나에 자잘한 기능이 많이 붙어있어서 아래의 체크박스를 만들어 놓고 하나씩 구현했다.

  • 인기 쇼핑 키워드 html 다시생성하기
  • 자동완성
    • 기본 스타일
      • 같은 단어 색칠
    • 인풋 이벤트
    • 데이터요청
    • 파싱
    • 템플릿에 넣기
    • 렌더링
    • 키보드 내리면 내려감
    • 디바운스

디바운스

200ms로 디바운스를 걸어서 fetch요청을 제한했다. 디바운스 함수를 유틸로 빼냈다.

처음에는 아래와 같이 timer를 반환시켜서 호출해주는 module에서 timer변수를 직접 관리해줬다. 이는 클로져를 이용해서 해결할 수 있다.

const debounce = (fn, delay, timer) => {
  if (timer) clearTimeout(timer);
  timer = setTimeout(fn, delay);
  return timer;
};

아래 코드와 같이 클로져 활용해서 모듈에서 timer 따로 관리하지 않게할 수 있다.

const initDebounce = (timer = null) => (fn, delay) => {
  if (timer) clearTimeout(timer);
  timer = setTimeout(fn, delay);
};

const debounce = initDebounce();

자동완성 아직 구현 못한 부분

캐시에 이전 검색했던 데이터가 저장돼있다면 fetch요청을 줄일 수 있을 것이다. 캐시를 이용하는 법도 배울겸 자동완성 데이터를 캐시에 저장했다가 재사용할 수 있게 구현하면 좋을 것 같다.

회고

1주일 전에 캐러셀 및 더보기 기능을 만들 때 쇼핑하우 사이트를 클론하였는데 거기에 추가로 검색창 쪽 기능만 추가했다. 그렇기 때문에 css를 거의 다루지 않아서 편하게? 기능 구현 쪽에 집중할 수 있었다.

항상 그렇지만 처음 구현해보는 기능들을 마주치면 어떻게 구현해야 될지 바로 안 떠오를 때가 많다. 그때마다 체크리스트를 만들면서 세세하게 나누고 하나씩 구현해나가보면 어떻게 구현할지 윤곽이 잡히게 되고 어느새 결과물이 나오는 점에서 재미를 느끼는 것이 아닌가라는 생각을 하게 된다.

아쉬운 점은 구현한 검색창 관련 기능이 그리 많은 편은 아니었다. 그렇지만 캐시 활용, 디바운싱 기법 활용, 자동완성을 재사용성이 있는 컴포넌트로 만들어보기 등 많은 부수적인 것들이 있었지만 이런저런 핑계로 제대로 구현하지 못한 아쉬움이 남는다.

일주일 단위로 시간이 정말 빠르게 지나간다. 빠르게 지나가는 만큼 학습하기로 한 시간만큼은 집중해서 몰입감 있게 하는 것이 중요한 것 같다. 다음 주는 제발 더 잘하자.

profile
Kyle 발전기

0개의 댓글