Navigate back to the homepage

Day6: Type-Ahead

JavaScript30
June 23rd, 2021 · 1 min read

專案介紹: 用 fetch 去 get 城市資料,並用正規表達式來回傳搜尋相關程式

作品頁面:https://iris1114.github.io/javascript30/06_Type-Ahead/index.html

做法:

  • fetch 取得城市資料
  • 取得輸入的值並用 regex 與城市資料的 city 及 state 做對比
  • 用 filter 取得對比成功的值,並回傳新陣列
  • 用此篩選好的新陣列再去呈現畫面

fetch & ajax

fetch 取得 json 資料:

1let cities = null;
2fetch(endpoint)
3 .then((res) => {
4 return res.json();
5 })
6 .then((res) => {
7 cities = res;
8 });

若是用 ajax 做法:(太久沒用 複習一下 XD)

1function requestHandle() {
2 console.log(JSON.parse(this.response));
3}
4
5let req = new XMLHttpRequest();
6req.addEventListener("load", requestHandle);
7req.open("get", endpoint);
8req.send();

正規表示法 Regular Expressions

正規表示法 (Regex) 是用來處理字串的方法,Regex 用自己一套特殊的符號表示法,讓我們可以很方便的搜尋字串、取代字串、刪除字串或測試字串是否符合樣式規則。

1const findMatches = (wordToMatch, cities) => {
2 return cities.filter((place) => {
3 const regex = new RegExp(wordToMatch, "gi");
4 return place.city.match(regex) || place.state.match(regex);
5 });
6};
  • RegExp() 物件用來建立正規式:第一個參數是正規式的內容,第二個參數是 flag。
  • g 表示 Global search,尋找整份文件,而不會找到就停。
  • i 表示 Case insensitive,表示不區分大小寫。
  • match() 方法可在字符串内找到指定的値,或找到一个或多個正規式的匹配。
1function numberWithCommas(x) {
2 return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
3}
  • 設定一個 numberWithCommas() 的方法,用於表達千分位。\B(?=(\d{3})+(?!\d)) 是千分位的正規式。

  • \d{3}匹配 3 個數字,+表示前面的内容重複 1 到多次,所以(\d{3})+ 表示三個數字的 1 到多次,也就是 3,6,9…等 3 的倍數個數字的字串

  • (?!\d) 匹配一个位置,此位置後面不是數字

  • (?=(\d{3})+(?!\d)) 匹配一个位置,這個位置後面首先是 3 的倍數個數字的字串,接下来的位置不是數字

  • /\B(?=(\d{3})+(?!\d))/g 就是全部匹配一个位置,這個位置前面要有字元存在,然後後面是 3 的倍數個數字,再後面是非數字。

replace() 、 match()

replace() 方法會傳回一個新字串,此新字串是透過將原字串與 pattern 比對,以 replacement 取代吻合處而生成。pattern 可以是字串或 RegExp,而 replacement 可以是字串或函式(會在每一次匹配時被呼叫)。

syntax: str.replace(regexp|substr, newSubstr|function)

範例

1var str = "Twas the night before Xmas...";
2var newstr = str.replace(/xmas/i, "Christmas");
3console.log(newstr); // Twas the night before Christmas...

match()方法檢索返回一個字符串匹配正則表達式的結果。

syntax: str.match(regexp)

範例

1var str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
2var regexp = /[A-E]/gi;
3var matches_array = str.match(regexp);
4
5console.log(matches_array);
6// ['A', 'B', 'C', 'D', 'E', 'a', 'b', 'c', 'd', 'e']

Code

1(() => {
2 const endpoint =
3 "https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json";
4
5 let cities = null;
6 fetch(endpoint)
7 .then((res) => {
8 return res.json();
9 })
10 .then((res) => {
11 cities = res;
12 });
13
14 //根據輸入字串filter符合city或place的結果
15 const findMatches = (wordToMatch, cities) => {
16 return cities.filter((place) => {
17 const regex = new RegExp(wordToMatch, "gi");
18 return place.city.match(regex) || place.state.match(regex);
19 });
20 };
21
22 //將人口數量進行千分位的表達
23 function numberWithCommas(x) {
24 return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
25 }
26
27 //將符合的值呈現至畫面
28 function handleChange() {
29 const matchArray = findMatches(this.value, cities);
30
31 const html = matchArray
32 .map((place) => {
33 const regex = new RegExp(this.value, "gi");
34 const cityName = place.city.replace(
35 regex,
36 `<span class="hl">${this.value}</span>`
37 );
38 const stateName = place.state.replace(
39 regex,
40 `<span class="hl">${this.value}</span>`
41 );
42 return `
43 <li>
44 <span class="name">${cityName}, ${stateName}</span>
45 <span class="population">${numberWithCommas(place.population)}</span>
46 </li>
47`;
48 })
49 .join("");
50 suggestions.innerHTML = html;
51 }
52
53 const search = document.querySelector(".search");
54 const suggestions = document.querySelector(".suggestions");
55
56 search.addEventListener("input", handleChange);
57})();

參考資料

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match https://ithelp.ithome.com.tw/questions/10195924 https://blog.epoch.tw/ https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/String/replace

More articles from Iris Blog

Day5: Flex Panels

練習 css flex 及 js 點擊圖片做展開效果

June 21st, 2021 · 1 min read

Day4: Array Cardio 1 💪

練習 array 的應用,包含 filter 、 map 、 sort 、 reduce

June 19th, 2021 · 1 min read
© 2020–2021 Iris Blog
Link to $mailto:qweichew@gmail.comLink to $https://github.com/iris1114Link to $https://www.instagram.com/iris.justdoit/Link to $https://www.linkedin.com/in/iris-chew