[javascript30] Type Ahead

하도야지·2021년 11월 19일
0

JavaScript30 따라하기

목록 보기
5/10

1. Type Ahead

  • 입력창에 검색어를 입력 시 검색어에 해당하는 데이터를 아래 목록으로 출력

2. 전체 코드

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Type Ahead 👀</title>
  <link rel="stylesheet" href="style.css">
</head>

<body>

  <form class="search-form">
    <input type="text" class="search" placeholder="City or State">
    <ul class="suggestions">
      <li>Filter for a city</li>
      <li>or a state</li>
    </ul>
  </form>
  <script>
    const endpoint = 'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json';

    const cities = [];

    const prom = fetch(endpoint)
      .then(blob => blob.json())
      .then(data => cities.push(...data));

    function findMatches(wordToMatch, cities) {
      return cities.filter(place => {
        const regex = new RegExp(wordToMatch, 'gi');
        return place.city.match(regex) || place.state.match(regex);
      })
    }

    function numberWithCommas(x) {
      return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
    }


    function displayMatches() {
      const matchArray = findMatches(this.value, cities);
      const html = matchArray.map(place => {
        const regex = new RegExp(this.value, 'gi');
        const cityName = place.city.replace(regex, `<span class="hl">${this.value}</span>`);
        const stateName = place.state.replace(regex, `<span class="hl">${this.value}</span>`);
        return `
          <li>
            <span class="name">${cityName}, ${stateName}</span>
            <span class="population">${numberWithCommas(place.population)}</span>
          </li>  
        `;
      }).join('');
      suggestions.innerHTML = html;
    }

    const searchInput = document.querySelector('.search');
    const suggestions = document.querySelector('.suggestions');

    searchInput.addEventListener('change', displayMatches);
    searchInput.addEventListener('keyup', displayMatches);

  </script>
</body>

</html>

3. 동작 순서

  1. fetch() 함수로 cities 배열에endpoint에서 가져온 데이터배열 입력한다.
  2. 검색창에 검색어를 입력한다.
  3. searchInput의 addEventListener에서 change, keyup 감지 후 displayMatches 함수 호출한다.
  4. displayMatches()에서 findMatches 함수 호출한다.
    3.1 findMatches() 에서 cities에서 검색조건에 맞는 데이터를 필터링 한다.
    3.2 필터링한 데이터를 목록으로 html <li>요소로 리턴한다.
    3.3 suggestions class에 html을 추가한다.
  5. 목록 출력 완료

4. HTML, CSS

innerHTML

innerHTML: 요소(element) 내에 포함 된 HTML 또는 XML 마크업을 가져오거나 설정

suggestions.innerHTML = html;

정규표현식(Reg)

그때그때 검색해서 쓰자
https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Regular_Expressions


5. JAVASCRIPT

fetch API

  • fetch: 자바스크립트를 사용하면서 필요할 때 서버에 네트워크 요청을 보내고 새로운 정보를 받아올 때 사용 가능한 함수.
  • 브라우저에 내장되어 있음
  • return 값으로 promise 객체가 반환됨
  • response.json() : 응답을 JSON형태로 파싱
    const prom = fetch(endpoint)
      .then(blob => blob.json())
      .then(data => cities.push(...data));

Array.prototype.join()

  • join() : 배열의 모든 요소를 연결해 하나의 문자열로 만드는 메서드
        const html = matchArray.map(place => {
          const regex = new RegExp(this.value, 'gi');
          const cityName = place.city.replace(regex, `<span class="hl">${this.value}</span>`);
          const stateName = place.state.replace(regex, `<span class="hl">${this.value}</span>`);
          return `
            <li>
              <span class="name">${cityName}, ${stateName}</span>
              <span class="population">${numberWithCommas(place.population)}</span>
            </li>  
          `;
        }).join('');
=> matchArray에 대해 각 요소를 `<l1>`요소로 만든 후 하나의 문자열로 합쳐 html요소로 만듬
profile
프로그래머를 꿈꾸는 코더

0개의 댓글