# [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)