잡다한 배똥월드

728x90

검색 페이지 관련

  • 페이지 진입 시 포커스가 input 에 가도록 처리하고, 키워드를 입력한 상태에서 input 을 클릭할 시에는 기존에 입력되어 있던 키워드가 삭제되도록 만들어야 합니다.
  • 필수 데이터를 불러오는 중일 때, 현재 데이터를 불러오는 중임을 유저에게 알리는 UI를 추가해야 합니다.
  • 필수 검색 결과가 없는 경우, 유저가 불편함을 느끼지 않도록 UI적인 적절한 처리가 필요합니다.
  • 최근 검색한 키워드를 SearchInput 아래에 표시되도록 만들고, 해당 영역에 표시된 특정 키워드를 누르면 그 키워드로 검색이 일어나도록 만듭니다. 단, 가장 최근에 검색한 5개의 키워드만 노출되도록 합니다.
  • 페이지를 새로고침해도 마지막 검색 결과 화면이 유지되도록 처리합니다.
  • 필수 SearchInput 옆에 버튼을 하나 배치하고, 이 버튼을 클릭할 시 /api/cats/random50 을 호출하여 화면에 뿌리는 기능을 추가합니다. 버튼의 이름은 마음대로 정합니다.
  • lazy load 개념을 이용하여, 이미지가 화면에 보여야 할 시점에 load 되도록 처리해야 합니다.
  • 추가 검색 결과 각 아이템에 마우스 오버시 고양이 이름을 노출합니다.

 


 

1. input에 자동 포커스

this.$searchInput.setAttribute("autofocus", "autofocus");

 

 

2. 기존 키워드 삭제

    this.$searchInput.addEventListener("click", function() {
      if ($searchInput.value != "") {
        $searchInput.value = "";
      }
    })

 

 

3. 로딩 ui, 검색 결과가 없을 때

     - App.js에 함수 추가

function loadingAnimation() {
  const word = ["l", "o", "a", "d", ".", "."];
  
  const loading = document.querySelector(".loading");
  const result = document.querySelector(".SearchResult");

  var position = 0;
  var timer = 0;
  result.style.display = "none";
  loading.style.display = "block";
  loading.innerText = "";

  for (var i = 0; i < intervals.length; i++) {
    clearInterval(intervals[i]);
  }

  intervals = [];
  var height = window.innerHeight - loading.getBoundingClientRect().top;
  loading.style.height = height + "px";
  loading.style.lineHeight = height + "px";

  var interval = setInterval(function() {
    if (timer > 2500) {
      clearInterval(interval);
      result.style.display = "grid";
      
      if (result.offsetHeight > 1) {
        loading.style.display = "none";
      } else {
        result.style.display = "none";
        loading.innerText = "검색 결과가 없습니다.";
      }

      return;
    }

    if (position == word.length) {
      loading.innerText = "";
      position = 0;
    } else {
      loading.innerText += word[position];
      position++;
    }
    
    timer += 200;

  }, 200);

  intervals.push(interval);
}

검색 결과가 없으면 SearchResult의 높이가 0이라서 만약에 로딩 애니메이션이 끝나고 SearchResult를 봤을 때 높이가 0이면 loading에 검색 결과가 없다는 문구를 보이게 만들었음.

 

 

5. 검색 키워드 추가 + 클릭시 재검색

     - App.js에 함수 추가

function createHistory(text) {
  const box = document.querySelector(".HistoryBox");
  const input = document.querySelector(".SearchInput");

  for (var i = 0; i < historyList.length; i++) {
    if (historyList[i].innerText == text) {
      box.removeChild(historyList[i]);

      historyList.splice(i, 1);
    }
  }
  
  const history = document.createElement("p");
  history.classList = "history";
  history.innerText = text;

  historyList.push(history);
  box.appendChild(history);

  history.addEventListener("click", function() {
    var word = history.innerText;
    input.value = word;
    input.dispatchEvent(new KeyboardEvent('keyup', {keyCode: '13'}));
  });

  if (historyList.length == 6) {
    var h = historyList.shift();
    box.removeChild(h);
  }
}

 

     - SearchInput.js에 코드 추가

    const HistoryBox = document.createElement("div");
    HistoryBox.classList = "HistoryBox";
    
    const historyTitle = document.createElement("p");
    historyTitle.innerText = "최근 검색 결과 : ";

    HistoryBox.appendChild(historyTitle);
    
    $target.appendChild(box);

SearchInput 밑에 HistoryBox를 만들어서 여기에 검색 기록인 history 를 추가함.

 

 

6. 새로고침 눌렀을 때 마지막 검색 결과 유지하기

     - SearchInput.js 코드 추가

    $searchInput.addEventListener("keyup", e => {
      if (e.keyCode == 13) {
        onSearch(e.target.value);
        sessionStorage.setItem("keyword", e.target.value);  //<- 추가
      }
    });


... (중략)... 


    if (sessionStorage.getItem("keyword") != null) {
      $searchInput.value = sessionStorage.getItem("keyword");
    }

 

     - App.js에 코드 추가

    this.searchInput = new SearchInput({
      $target,
      onSearch: async keyword => {
        createHistory(keyword);
        loadingAnimation();
        const {data} = await api.fetchCats(keyword);
        this.setState(data);
        sessionStorage.setItem("data", JSON.stringify(data));  //<- 추가
      }
    });

 

     - SearchResult.js에 코드 추가

    if (sessionStorage.getItem("data") != null) {
      this.data = JSON.parse(sessionStorage.getItem("data"));
    }

렌더링 하기 전에 this.data 채워서 렌더링하면 해당 데이터로 item 생성됨.

 

 

7. /api/cats/random50

     - App.js에 코드 추가

    this.searchInput = new SearchInput({
      $target,
      onSearch: async keyword => {
        createHistory(keyword);
        loadingAnimation();
        const {data} = await api.fetchCats(keyword);
        this.setState(data);
        sessionStorage.setItem("data", JSON.stringify(data));
      },
      /*추가*/
      onRandom: async () => {
        loadingAnimation();
        const {data} = await api.fetchRandom();
        this.setState(data);
        sessionStorage.setItem("data", JSON.stringify(data));
      }
    });

 

     - api.js에 코드 추가

  fetchRandom: async () => {
    const result = await fetch(`${API_ENDPOINT}/api/cats/random50`);
    return result.json();
  }

 

 

나머지 추후 수정

728x90

+ Recent posts