Dev/JavaScript30

6. Type Ahead ( JavaScript30 )

takeU 2021. 7. 8. 11:56
반응형

Type Ahead

웹에서 정보를 받아와 Live Search 기능을 구현

 

기본 코드

<!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'; 
        </script>
    </body> 
</html>

 

목표

이번엔 스타일시트가 따로 빠져있는데 자바스크립트를 공부하는 목적이므로 따로 첨부는 하지 않음.

검색창을 만들어서 도시나 주의 이름의 일부를 검색하면 도시, 주, 인구수를 실시간으로 보여주도록 만들 예정

 

과정

  1. 도시와 주의 이름과 인구수를 받아옴
  2. 검색시 일치하는 값을 찾아내는 함수를 만듦
  3. 위의 함수를 이용해 화면에 보여지게하는 함수를 만듦
  4. 인구수를 보기 편하게 콤마를 삽입하는 함수를 만들어줌
  5. 만든 함수를 통해 실시간으로 브라우저에 출력

 

코드 분석

1. 도시와 주의 이름과 인구수를 받아옴

 const cities = [];

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

cities라는 빈 배열을 생성하고, fetch()를 사용함

2. 검색시 일치하는 값을 찾아내는 함수를 만듦

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

검색시 단어가 일치하는 도시 또는 주를 반환하는 변수 regex를 만들고
cities에 필터를 적용해 반환하도록 하는 findMatches 함수를 만든다.
이 때 RegExp는 검색할때 패턴을 설정해 줄 수 있는 생성자이고,
'gi'는 전체에서 대소문자를 구분하지 않고 검색한다는 의미이다.

3. 위의 함수를 이용해 화면에 보여지게하는 함수를 만듦

 const 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>
         ${cityName}, ${stateName}
         ${numberWithCommas(place.population)}
               </li>`
   }).join('');
   suggestions.innerHTML = html;
}

matchArray에 일치하는 값을 담고, html에 검색 후에 배열에서 일치하는 내용을 찾아
cityName, stateName에 새로운 검색값이 들어간 html태그로 대체하도록 하고,
새로운 리스트 태그를 반환하고 공백으로 서로를 연결하게 해서
suggestions에 html내용을 스크립트로 삽입하는 이 모든과정을 displayMatches함수에 담는다

4. 인구수를 보기 편하게 콤마를 삽입하는 함수를 만들어줌

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

해당 함수는 stackoverflow 참조

5. 만든 함수를 통해 실시간으로 브라우저에 출력

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

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

searchInputsearch 클래스를 포함하는 요소들을 담고,
suggestions에는 suggestions 클래스를 포함하는 요소들을 담는다.
searchInputchange이벤트와 keyup이벤트가 실행될 때 displayMatches함수를 실행

 

찾아본 내용, 알게된 내용들

정규표현식 RegExp(pattern[, flags]) flags 종류

  1. g(전체에서 일치하는 모든문자 검색)
  2. i(대소문자 구별하지 않음)
  3. m(다중행에 적용)