Javascript30 - Type Ahead



Learning Point

  • fetch APIを勉強します.
  • Regular式を学習します.
  • 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(콜백);
    アドレス値は必須パラメータです.fetch APIはajax通信の成功/失敗にかかわらず、承諾を返す.fetch関数を使用すると、リソースを非同期で要求できます.
    MDNが提供するコードの例は次のとおりです.
    fetch('http://example.com/movies.json')
      .then(function(response) {
        return response.json();
      })
      .then(function(myJson) {
        console.log(JSON.stringify(myJson));
      });
    まず、fetch APIは応答オブジェクトを返す.これは実際のJSONではなく簡単なHTTP応答であるため,json()法を用いて応答対象からjsonとして解析する必要がある.

    regular expression

    const regex = new RegExp(input.value, "gi"); 
    「g」は、グローバル一致を検索するすべての文字列を表す.
    「i」は、insensitive、ignore caseを使用して大文字と小文字を区別しないことを意味します.
    regular expressionについては、近々発表されるので簡単に整理しました.