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. 도시와 주의 이름과 인구수를 받아옴
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);
searchInput
에 search
클래스를 포함하는 요소들을 담고,suggestions
에는 suggestions
클래스를 포함하는 요소들을 담는다.searchInput
에 change
이벤트와 keyup
이벤트가 실행될 때 displayMatches
함수를 실행
찾아본 내용, 알게된 내용들
정규표현식 RegExp(pattern[, flags]) flags 종류
- g(전체에서 일치하는 모든문자 검색)
- i(대소문자 구별하지 않음)
- m(다중행에 적용)