노트

[클라우딩 어플리케이션 엔지니어링 TIL] - 7주차 고양이 검색 사이트 2 본문

TIL

[클라우딩 어플리케이션 엔지니어링 TIL] - 7주차 고양이 검색 사이트 2

blackmilktea 2024. 5. 30. 23:15

고양이 검색 사이트 만들기 2

요구사항

3. 검색 페이지 관련

● 페이지 진입 시 포커스가 input 에 가도록 처리하고, 키워드를 입력한 상태에서 input 을 클릭할 시에는 기존에 입력되어 있던 키워드가 삭제

● *데이터를 불러오는 중일 때, 현재 데이터를 불러오는 중임을 유저에게 알리는 UI를 추가

더보기
/* Loading.js */
class Loading {
  $loading = null;
  data = null;
  constructor({ $target }) {
    const $loading = document.createElement('div');
    this.$loading = $loading;
    $target.appendChild(this.$loading);
    this.data = {show: false}
    this.render()
  }
  show() { this.setState({show: true}); }
  hide() { this.setState({show: false}); }
  setState(nextData) {
    this.data = nextData;
    this.render();
  }
  render() {
    if (this.data.show) {
      this.$loading.innerHTML = `
              <div class="Loading">
              <p>Loading</p>
              </div>
            `;
    } else { this.$loading.innerHTML = ''; }
  }
}

/* Loading css */
.Loading {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  background: rgba(0,0,0,0.3);
  text-align: center;
}
.Loading p {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 40px;
}

Loading UI

*검색 결과가 없는 경우, 유저가 불편함을 느끼지 않도록 UI적인 적절한 처리

+

 

 

 

● 최근 검색한 키워드를 SearchInput 아래에 표시되도록 만들고, 해당 영역에 표시된 특정 키워드를 누르면 그 키워드로 검색이 일어나도록 만듭니다. 단, 가장 최근에 검색한 5개의 키워드만 노출되도록 합니다.

● 페이지를 새로고침해도 마지막 검색 결과 화면이 유지되도록 처리

→ sessionStorage를 이용해서 검색어, 검색 결과 저장

더보기
// KeywordHistory.js
class KeywordHistory {
  $keywordHistory = null;
  data = null;

  constructor({ $target, onSearch }) {
    const $keywordHistory = document.createElement('ul')
    this.$keywordHistory = $keywordHistory;
    this.$keywordHistory.className = "KeywordHistory"
    $target.appendChild(this.$keywordHistory);

    this.onSearch = onSearch;
    this.init();
    this.render();
  }

  init() {
    const data = this.getHistory();
    this.setState(data);
  }

  addKeyword(keyword) {
    let keywordHistory = this.getHistory();
    keywordHistory.unshift(keyword);
    keywordHistory = keywordHistory.slice(0, 5);
    sessionStorage.setItem('keywordHistory', keywordHistory.join(','));
    this.init();
  }

  getHistory() {
    return sessionStorage.getItem('keywordHistory')
    === null ? [] : sessionStorage.getItem('keywordHistory').split(',');
  }

  setState(nextData) {
    this.data = nextData;
    this.render();
  }

  render() {
    this.$keywordHistory.innerHTML = this.data
      .map(
        keyword => `<button>${keyword}</button>`
      ).join('');
    this.$keywordHistory.querySelectorAll('button')
      .forEach(($item, index) => {
        $item.addEventListener('click', () => {
          this.onSearch(this.data[index]);
        });
      });
  }
}
/* App.js */
//...
  this.searchInput = new SearchInput({
    $target,
    onSearch: (keyword) => {
      this.Loading.show();
      api.fetchCats(keyword).then(({ data }) => {
        this.setState(data);
        this.Loading.hide();
        // 세션에 저장
        this.saveResult(data);
      });
    }
  });
  saveResult(result) {
    this.data = result;
    // JSON.stringify으로 String으로 저장
    sessionStorage.setItem('lastResult', JSON.stringify(result));
  }

  init() {
    // JSON.parse로 저장된 String을 다시 배열로 변환
    const lastResult = sessionStorage.getItem('lastResult') === null
    ? [] : JSON.parse(sessionStorage.getItem('lastResult'));
    this.setState(lastResult);
  }

 *SearchInput 옆에 버튼을 하나 배치, 이 버튼을 클릭할 시 /api/cats/random 을 호출하여 화면에 뿌리는 기능을 추가

최근 검색어, 랜덤 버튼 기능

● lazy load 개념을 이용하여, 이미지가 화면에 보여야 할 시점에 load 되도록 처리

+