Javascript30 - Type Ahead

기록일기📫·2020년 12월 18일
0

javascript30

목록 보기
7/16

Learning Point

  • fetch API에 대해 학습한다.
  • Regular expression에 대해 학습한다.
  • json에 대해 학습한다.

HTML Part

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Type Ahead 👀</title>
    <link rel="stylesheet" href="style.css" />
    <script defer src="index.js"></script>
  </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>
  </body>
</html>

CSS Part

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;
}

Javascript Part

const endpoint =
  "https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json";

const cities = [];

fetch(endpoint)
  .then((res) => {
    console.log(res);
    return res.json(); // body text를 json으로 읽어 promise를 return
  })
  .then((data) => {
    cities.push(...data);
  });

const input = document.querySelector(".search");
const suggestion = document.querySelector(".suggestions");

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

getCity = () => {
  suggestion.innerHTML = findMatch(cities, input.value)
    .map((place) => {
      const regex = new RegExp(input.value, "gi");
      const city = place.city.replace(
        regex,
        `<span class="hl">${input.value}</span>`
      );
      const state = place.state.replace(
        regex,
        `<span class="hl">${input.value}</span>`
      );
      return `<li>
      <span class="name">${city} ${state}</span>
      <span class="population">${place.population}</span>
      </li>`;
    })
    .join("");
};

input.addEventListener("change", getCity);
input.addEventListener("keyup", getCity);

fetch API

기본적으로 fetch()는 다음과 같은 2개의 매개변수를 받는다.

fetch('주소', 설정객체).then(콜백).catch(콜백);

주소값은 필수 parameter이다. fetch API는 ajax 통신의 성공/실패 여부와 관계없이 promise를 리턴한다. fetch함수를 사용하면 리소스를 비동기로 요청할 수 있다.

MDN이 제공하는 예시 코드는 다음과 같다.

fetch('http://example.com/movies.json')
  .then(function(response) {
    return response.json();
  })
  .then(function(myJson) {
    console.log(JSON.stringify(myJson));
  });

일차적으로 fetch API는 response 객체를 반환한다. 이것은 단순한 HTTP Response이며, 실제 JSON이 아니기 때문에, response 객체로부터 json() 메서드를 이용해 json 형태로 parsing해야 한다.

regular expression

const regex = new RegExp(input.value, "gi"); 

"g"는 global로, match하는 모든 문자열을 찾아주겠다는 의미이고,
"i"는 insensitive, ignore case로 대소문자를 구문하지 않는다는 의미이다.
regular expression에 대해서는 조만간 포스팅을 올릴 예정이므로 간단히만 정리했다.

0개의 댓글