Javascript小型專案練習8 Type-ahead(JS30-6)

今天繼續來做JS30~!這篇其實花了我不少的時間,原因在於在專案中也幾個函式我並沒有接觸過,花了一些時間查資料,結果又打開了新的潘朵拉盒子~整個就沒完沒了~!
回到主題,這次的專案練習主要有幾個目標:
1.打造一個類似searchbar的功能,用來搜尋json檔案內的資料
2.根據鍵入的文字,直接在下方框顯示搜尋結果(有點類似autocomplete的功能)
3.highlight搜尋結果中符合條件的文字,例如鍵入bos 會做出類似Boston的效果

HTML

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

CSS

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

const endpoint = 'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json';
    const cities = []
    const input_search = document.querySelector('.search')
    const suggestions = document.querySelector('.suggestions')
    fetch(endpoint)
      .then(response => response.json())
      .then(json => cities.push(...json));


    input_search.addEventListener('change', display)
    input_search.addEventListener('keyup', display)


    function numberWihCommas(x) {
      return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
    }

    function FindMacthes(wordToMatch, cities) {
      return cities.filter(item => {
        let re = new RegExp(wordToMatch, 'gi')
        return item.city.match(re) || item.state.match(re)
      })

    }

    function display() {
      const MatchArray = FindMacthes(this.value, cities)
      let html = MatchArray.map(item => {
        const regrex = new RegExp(this.value, 'gi')
        const newName = item.city.replace(regrex, `<span class ='hl'>${this.value}</span>`)
        const newState = item.state.replace(regrex, `<span class ='hl'>${this.value}</span>`)
        return `
          <li>
            <span class = 'name'>${newName} , ${newState}</span>
            <spna class = 'population'> ${numberWihCommas(item.population)}</span>
          </li>
        `;
      }).join('');
      suggestions.innerHTML = html;
      console.log(MatchArray);
    } 

學習重點

  • 練習初次接觸的fetch功能,注意fetch首先會回傳一個promise,資料可用.json、.text、.blob方法讀取
  • 由將數字加入千分位的函式(x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ‘,’)複習regrex positive lookahead & negative lookahead 以及\B的意義(找尋非邊界的位置)
  • 利用map&join將陣列內的內容轉為字串存放在li的結構裡面(實用)
  • 利用動態regrex配合css做出類似autocomplete的效果(一旦關鍵字match資料庫,在form內便新增對應的li)

最終成品

參考文章

正则表达式/\B(?=(\d{3})+(?!\d))/怎样给数字添加千分符的
RegExp 應用: lookahead , lookbehind

廣告

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s