์น์์ ์ ๋ณด๋ฅผ ๋ฐ์์ Live Search๊ธฐ๋ฅ์ ๊ตฌํ
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>Type Ahead ๐</title>
<link rel="stylesheet" href="style_JuneHyung.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>
html {
box-sizing: border-box;
background: #ffc600;
font-family: 'helvetica neue';
font-size: 20px;
font-weight: 200;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
input {
width: 100%;
padding: 20px;
}
.search-form {
max-width: 400px;
margin: 50px auto;
}
input.search {
margin: 0;
text-align: center;
outline: 0;
border: 10px solid #f7f7f7;
width: 120%;
left: -10%;
position: relative;
top: 10px;
z-index: 2;
border-radius: 5px;
font-size: 40px;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.12), inset 0 0 2px rgba(0, 0, 0, 0.19);
}
.suggestions {
margin: 0;
padding: 0;
position: relative;
/*perspective: 20px;*/
}
.suggestions li {
background: white;
list-style: none;
border-bottom: 1px solid #d8d8d8;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.14);
margin: 0;
padding: 20px;
transition: background 0.2s;
display: flex;
justify-content: space-between;
text-transform: capitalize;
}
.suggestions li:nth-child(even) {
transform: perspective(100px) rotateX(3deg) translateY(2px) scale(1.001);
background: linear-gradient(to bottom, #ffffff 0%, #efefef 100%);
}
.suggestions li:nth-child(odd) {
transform: perspective(100px) rotateX(-3deg) translateY(3px);
background: linear-gradient(to top, #ffffff 0%, #efefef 100%);
}
span.population {
font-size: 15px;
}
.hl {
background: #ffc600;
}
๋๋ฌธ์ ๋๋ ์๋ฌธ์๋ก ๋ฐ๊พธ๋ ์์ฑ์ผ๋ก, uppercase, lowercase๋ฅผ ์์ฃผ์ป๋๋ฐ,
capitalize๋ ์ฒ์ ๋ดค๋ค.
capitalize : ๋จ์ด์ ์ฒซ๋ฒ์งธ ๊ธ์๋ฅผ ๋๋ฌด๋ฎ๋ก ๋ฐ๊ฟ๋๋ค.
perspective๋ฅผ ์ฌ์ฉํ์ง ์์ผ๋ฉด translateZ์ ๋ณํ๋ฅผ ๋๋ ์ ์๋ค.
perspective๋ฅผ ์ฌ์ฉํด ์๊ธ๊ฐ์ ์ฃผ๋ฉด ์ฐจ์ด๋ฅผ ๋๋ ์ ์๋ค.
์ฐธ๊ณ :
https://gahyun-web-diary.tistory.com/80
https://developer.mozilla.org/ko/docs/Web/CSS/CSS_Transforms/Using_CSS_transforms
์ ๊ฐ๊ตฌ๋ฌธ (Spread syntax)
๋์ดํ ์๋ฃ๋ฅผ ์ถ์ถํ๊ฑฐ๋ ์ฐ๊ฒฐํ ๋ ์ฌ์ฉ.
์ฌ์ฉ ๋ฐฉ๋ฒ์ ๋ฐฐ์ด์ด๋ ๊ฐ์ฒด, ๋ณ์๋ช ์์ ๋ง์นจํ 3๊ฐ(...)๋ฅผ ์ ๋ ฅํฉ๋๋ค.
! ๋ฐฐ์ด,๊ฐ์ฒด, ํจ์ ์ธ์ ํํ์([],{},()) ์์์๋ง ์ฌ์ฉ.
ํจํด์ ์ฌ์ฉํด ํ ์คํธ๋ฅผ ํ๋ณํ ๋ ์ฌ์ฉ.
RegExp
๊ฐ์ฒด๋ ๋ฆฌํฐ๋ด ํ๊ธฐ๋ฒ๊ณผ ์์ฑ์๋ก์จ ์์ฑํ ์ ์์ต๋๋ค.
/ab+c/i
new RegExp(/ab+c/, 'i') // ๋ฆฌํฐ๋ด
new RegExp('ab+c', 'i') // ์์ฑ์
new` `RegExp(pattern [,flags]) ``// ์์ฑ์ ๋ฐฉ์``/pattern/flags ``// ์ ๊ทํํ์ ๋ฆฌํฐ๋ด
์ธ์๋ช | ๋ฐ์ดํฐํ | ํ์/์ต์ | ์ค๋ช |
---|---|---|---|
pattern | string | ํ์ | ์ ๊ทํํ์ |
flags | ์ต์ | g : ํ
์คํธ ์ ์ฒด์์ ์ผ์นํ๋ ๋ฌธ์๋ฅผ ์ฐพ์ ๋, ์ง์ ํ์ง ์์ผ๋ฉด ์ฒซ๋ฒ์งธ ์ผ์นํ๋ ๋ฌธ์๋ง ๊ฒ์ i : ๋์๋ฌธ์๋ฅผ ๊ตฌ๋ถํ์ง ์๋๋ค. m :^(์ฒซ๋ฒ์งธ ๋ฌธ์)์ $(๋ง์ง๋ง ๋ฌธ์)๊ฐ (\n, \r๋ก ๊ตฌ๋ถ๋๋) ํ๋จ์๋ก ์ผ์น |
์ ๊ทํํ์์ ๋ค์๊ณผ ๊ฐ์ ๊ฒฝ์ฐ ์ฌ์ฉํ๋ค.
Character | Meaning |
---|---|
\ | ์ด์ค์ผ์ดํ(escaping) |
^ | ๋ฒ์, ์์ ์ง์ , |
$ | ๋ฒ์, ๋๋๋ ์ง์ |
* | ์๋, ์๊ฑฐ๋ ๋ ๋ง๋ค == {0,} |
+ | ์๋, 1๋ณด๋ค ๋ง๋ค. == {1,} |
? | ์๋, ์๊ฑฐ๋ ํ๋์ด๋ค. |
. | ์ผ์น, ๋ฌธ์ ํ๋์ ์ผ์น |
(*x*) | ์ผ์น, x์ ์ผ์นํ๋ ๊ฒ์ ์ฐพ์ ํ์ ์ด์ ์ ๊ทผํ ์ ์๋๋ก ํจ |
x|y | ์ผ์น. x๋ y์ ์ผ์น |
t{n} | ์๋. t์ n๋ฒ ์ผ์นํ๋ ๋ฌธ์์ด๊ณผ ์ผ์น |
t{n,} | ์๋, t์ n๋ฒ ์ด์ ์ผ์นํ๋ ๋ฌธ์์ด๊ณผ ์ผ์น |
t{n,m} | ์๋. t์ n๋ฒ ์ด์ m๋ฒ ์ดํ๋ก ์ผ์นํ๋ ๋ฌธ์์ด๊ณผ ์ผ์น |
[xyz] | ์ผ์น. xyz์ค์ ํ๋๋ผ๋ ์ผ์นํ๋ ๋ฌธ์์ด๊ณผ ์ผ์น |
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
์ ๊ท์์ ์ด์ฉํ์ฌ ์ซ์๋ฅผ 1000๋จ์๋ก ๋์ด ์ฝค๋ง ์ฝ์ .
์ ๊ทํํ์์๋ํด ๊ณต๋ถํ์.
/\B(?=(\d{3})+(?!\d))/g
\b
: ๋จ์ด์ ๊ฒฝ๊ณ(์์๊ณผ ๋)๊ฐ ์๋๋ถ๋ถ
(\d{3})
:
\d
: ์ซ์ ๋ฌธ์ ๋์{n}
: ์ ํํ์์ด n๋ฒ ๋์ค๋ ๋ถ๋ถ์ ๋์.=> ์ฆ, ์ซ์๊ฐ 3๋ฒ
+(?!\d)
:
+
: ์์ ํํ์์ด 1ํ ์ด์ ์ฐ์์ผ๋ก ๋ฐ๋ณต๋๋ ๋ถ๋ถ๊ณผ ๋์x(?!y)
: x๋ค์ y๊ฐ ์๋ ๊ฒฝ์ฐ์๋ง x์ ์ผ์น=> ์ฆ, (?!\d)
๋ ๋ค์ ๋์ด์ ์ซ์๊ฐ ์๋ ๊ฒฝ์ฐ๋ฅผ ์๋ฏธ.
(?=
~~~ )
: ์ ๋ค ์กฐ๊ฑด ๋ชจ๋ ๋ง์กฑ.
const endpoint = 'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json';
const cities =[];
// const porm = fetch(endpoint);
// console.log(porm);
// fetch(endpoint).then(blob => console.log(blob));
fetch(endpoint)
.then(blob => blob.json())
.then(data=> cities.push(...data));
blob ๊ฒฐ๊ณผํ๋ฉด
๊ทธ๋ฅ data๋ฅผ cities์ ๋ฃ์ผ๋ คํ ๋ error๋ฐ์
ํ์ ์ด ์๋ง์์ ๋ฐ์ํ๋๊ฑฐ ๊ฐ์์.
fetch(endpoint)
.then(blob => blob.json())
.then(data=> cities = data);
Uncaught (in promise) TypeError: Assignment to constant variable. ๋ฐ์
function findMatches(wordToMatch, cities){
return cities.filter(place => {
// here we need to figure out if the city on state matches what was searched
// ์ฌ๊ธฐ์ ์ฐ๋ฆฌ๋ ์ฃผ์ ๋์๊ฐ ๊ฒ์๋๋ ๊ฒ๊ณผ ์ผ์นํ๋ ์ง ์์ ๋ด์ผํฉ๋๋ค.
const regex = new RegExp(wordToMatch, 'gi');
return place.city.match(regex) || place.state.match(regex);
})
}
๋จ์ด๊ฐ ์ผ์นํ๋ ๋์ or ์ฃผ๋ฅผ ๋ฐํํ๋ ๋ณ์ regex๋ฅผ ๋ง๋ค๊ณ , ํํฐ๋ฅผ ์ ์ฉํด ๋ฐํํ๋๋กํ๋ findMatchesํจ์๋ฅผ ๋ง๋ฌ.
RegExp๋ ๊ฒ์ํ ๋ ํจํด์ ์ค์ ํด ์ค ์ ์๋ ์์ฑ์์ด๊ณ , gi๋ ์ ์ฒด์์ ๋์๋ฌธ์๋ฅผ ๊ตฌ๋ถํ์ง์๊ณ ๊ฒ์ํ๋ค๋ ์๋ฏธ.
g i m ๋ถ์ฌ์ธ ์ ์๋๋ด!
function displayMatches(){
// console.log(this.value);
const matchArray = findMatches(this.value, cities);
// console.log(matchArray);
const html = matchArray.map(place => {
const regex = new RegExp(this.value, 'gi');
const cityName = place.city.replace(regex, `<span classs="h1"> ${this.value}</span>`);
const stateName = place.state.replace(regex, `<span classs="h1"> ${this.value}</span>`);
return `
<li>
<span class="name">${cityName}, ${stateName}</span>
<span class="population">${numberWithCommas(place.population)}</span>
</li>`
}).join('');
suggestions.innerHTML = html;
}
์
๋ ฅํ ๊ฐ(this.value
)๊ณผ ๋ฐ์์จ ๋์(cities
)๋ฅผ ๋งค์นํด์ matchArray์ ์ ์ฅ.
const matchArray = findMatches(this.value, cities);
html์ ๊ฒ์ ํ์ ๋ฐฐ์ด์์ ์ผ์นํ๋ ๋ด์ฉ์ ์ฐพ์ cityName๊ณผ stateName์ ์๋ก์ด ๊ฒ์๊ฐ์ด ๋ค์ด๊ฐ htmlํ๊ทธ๋ก ๋์ฒดํ๋๋กํ๊ณ , ์๋ก์ด ๋ฆฌ์คํธ ํ๊ทธ๋ฅผ ๋ฐํ.
suggenstions์ html๋ด์ฉ์ ์คํฌ๋ฆฝํธ๋ก ์ฝ์ ํ๋ ๋ชจ๋ ๊ณผ์ ์ displayMatches์ ๋ด๋๋ค.
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
์ ๊ทํํ์์ ์ด์ฉํด ๋ง๋ฌ.
input์ ๊ฐ์ด ๋ณํ ๋์ keyup event๊ฐ ๋ฐ์ํ ๋๋ง๋ค displayMatches๋ฅผ ๋์์ํด.
searchInput.addEventListener('change', displayMatches);
searchInput.addEventListener('keyup', displayMatches);