---
# System prepended metadata

title: '[JS30] Day.6  Ajax Type Ahead'
tags: [JS30]

---

# [JS30] Day.6  Ajax Type Ahead
###### tags: `JS30`
## 任務 Task
做一個搜尋欄，打字時可以同步抓取 `json` 資料並顯示出來。

==完成時間：2hr==
## 步驟 Step
1. 監聽輸入欄 `keyup` 或 `input` 使輸入文字時就發生改變，用 `chage` 的話要跳出輸入欄才會發生變化。
1. 用 `fetch().than` 將 `json` 資料變成 `Array`
2. 用 `filter` 篩選符合文字的項目利用 `match` 去找尋符合的關鍵字。
3. 用 `map` 將 `object` 裡的文字改成 `html` 形式，好方便加入 `innerHTML`。
4. 用 `replace` 改 `object` 的文字為 `html` 好加入樣式。
5.  將數字內容用 `replace` 改成三位一個逗號的形式

## 筆記 Note
### text-transform capitalize
* 用法：定義文字大小寫。
```css=
text-transform: uppercase; /*所有字母均大寫*/
text-transform: lowercase; /*所有字母均小寫*/
text-transform: capitalize; /*第一個字母大寫，其他字母小寫*/
```
### transform perspective
* 用法：呈現 3D 效果。
* 數字越大代表離螢幕越遠。
* 參考：https://eyesofkids.gitbooks.io/css3/content/contents/transform3d.html
```css=
transfrm: perspective(100px);
```
### JS fetch().than
* 是一種 `API` 可以操作 `http` 的資料。
* 回傳 `promise` 用 `then` 做為下一步，會將回傳的資料傳到下一個 `then` 。
* 可以使用 `blob()` `json()` `text()` 讀取  `promise` 資料。 
### JS RegExp
* `RegExp` 物件被用來比對符合自訂規則的文字。
* 建構 `RegExp` 物件有兩種方法：
    * 文字表達法（literal notation）：
        頭尾以==斜線==標註，不使用引號。
    * 建構子涵式（constructor）：
        頭尾以==引號==標註，不使用斜線。
```javascript=
const regex = new RegExp(/abc/,'gi')
//'gi'為 flag 設定
//g 為比對字串所有位置，i 為不分大寫
```
### JS Array.replace()
* 回傳一個新字串，透過將原字串與 `pattern` 做比對，進行函數或字串的替換。
* `pattern` 可以是字串或是 `RegExp`。
```javascript=
let str = 'apple';
let newStr = str.replace('pp', 'ba');
console.log(str, newStr);
//output: apple abale
```
### JS String.match()
* 用於在字串中搜尋與設定的正規表達式匹配的項目，找到則將匹配的項目以 `array` 返回，沒找到則返回 `Null`
```javascript=
let str = 'banana';
let reg = new RegExp(/p/,'gi');
console.log(str.match(reg));
//output: ['p','p']
```
* 搭配 `filter` 可篩選符合條件的 `array` 裡的字串。
```javascript=
let array = ['banana', 'apple', 'bear', 'ear'];
let reg = new RegExp(/ea/, 'gi');
let newArray = array.filter(item => {
    console.log(item.match(reg));
    //output: null null ['ea'] ['ea']
    return item.match(reg);
});
console.log(newArray);
//output: ['bear', 'ear']
```
### JS Array.join()
* 將陣列所有元素連接合併成一個字串並回傳。
* 預設間隔為 `","`。
```javascript=
const elements = ['abc', 'def', 'gh'];
console.log(elements.join());
//output: 'abc,def,gh'
console.log(elements.join(''));
//output: 'abcdefgh'
console.log(elements.join('-'));
//output: 'abc-def-gh'
```
## 遇到問題 Problem
:::danger
⚠️ <font color=black>Problem</font>
:::
不知道為甚麼要用 `match` ，試試看用 `includes`。
:::info
:ok_hand: <font color=black>Revise</font>
:::
用 `includes` 也可以，不過文字須完全一樣才能符合條件。用 `match` 可以更加嚴謹的設立條件。
## 想法 Idea
:::warning
:bulb: <font color=black>抓取氣象局資料，建立一個下拉式選單，選去不同縣市時，顯示他的氣象資料。
</font>
:::

### 方法 method
* `fetch` 的方法跟他教的一樣，建立一個 `Array` 裡面放氣象局的 `location` 資料，不過要先取出需要的，使用 `chrome` 的 `json` 擴充可以很方便看出要的資料在哪。
* 要注意的是，`fetch` 因為同步及非同步問題，所以在後面執行 `function` 裡的 `json` 資料是跑不出來的，要在 `fetch().then(呼叫function)`裡面先呼叫 `function` 才能在`console.log()` `json` 資料時能顯現出來。
* 監聽用的是 `change` ，是監聽 `select` 的 `value` 變化。
<iframe height="300" style="width: 100%;" scrolling="no" title="Weather API" src="https://codepen.io/jim876633/embed/bGLzEKa?default-tab=result" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
  See the Pen <a href="https://codepen.io/jim876633/pen/bGLzEKa">
  Weather API</a> by Jim (<a href="https://codepen.io/jim876633">@jim876633</a>)
  on <a href="https://codepen.io">CodePen</a>.
</iframe>

## 連結
[RegExp介紹](https://5xruby.tw/posts/15min-regular-expression)