預期結果
透過cities.json
取得城市資料清單
在search輸入框輸入關鍵字後
下方要即時顯示符合結果的資料
並把符合字串用黃色背景標記
功能拆解
分為取得cities資料和利用regex過濾資料
Fetch API
HTML5提供的API,fetch()
回傳promise物件
簡易GET用法如MDN web docs範例
fetch('https://example.com/example.json')
.then(function(response){
return response.json();
})
.then(function(myjson){
console.log(myjson)
})
印出fetch後的response,結果如下
同Fetch API Response文件說明,結果資料在body中
但沒有告訴它格式是image? html? json?
使用內建的json()
將資料轉成json
Spread operator
ES6出現的新特性,把陣列展開成個別的值
要merge成一個新陣列時很好用
let newArr1=['a','b','c']
let newArr2=[1,2,3]
let resultArr=[...newArr1,...newArr2]
// resultArr=['a','b','c',1,2,3]
也可以用concat
的寫法
let newArr1=['a','b','c']
let newArr2=[1,2,3]
let resultArr=newArr1.concat(newArr2)
spread處理的複製 屬於shallow copy(copy到物件第一層,第二層仍是參照到記憶體位址)
例如:
let obj ={papa:'peng',mom:'hou',child:{older:'chen',young:'shan'}
let newObj={...obj}
試著改變原obj的第一層papa值&第二層child.older的值
回到cities的處理
const endpoint = 'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json'
const cities = []
fetch(endpoint)
.then((blob) => blob.json())
.then((data) => cities.push(...data))
每筆資料格式如下:
filter()
let newArray=array.filter(function(item){
return condition;
})
逐一驗證item是否符合condition,返回一個新的陣列!
String.match()
參考String.prototype.match()-MDN web docs
str.match(regexp)
,使用string.match(regex)判斷字串中是否有符合regex的內容,若有找到符合的以陣列回傳結果,若沒有符合的回傳null
Regex
常用flag:
- i :case-insensitive 大小寫都要!
- g :looks for all matchs 字串全部搜尋,不會找到一個就停止
建立Regex物件
// long syntax
regexp = new RegExp("pattern", "flags");
// short
regexp = /pattern/; // no flags
regexp = /pattern/gmi; // with flags g,m and i (to be covered soon)
內容摘自javascript.info
回到cities搜尋
// find match cities
function findMatch(word, cities) {
// 回傳結果(陣列形式)
return cities.filter((place) => {
const reg = new RegExp(word, 'gi')
// filter條件: city or state含有搜尋字串
return place.city.match(reg) || place.state.match(reg)
})
}
最後完成結果
const endpoint =
'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json'
const cities = []
fetch(endpoint)
.then((blob) => blob.json())
.then((data) => cities.push(...data))
// find match cities
function findMatch(word, cities) {
// 回傳結果(陣列形式)
return cities.filter((place) => {
const reg = new RegExp(word, 'gi')
// filter條件: city or state含有搜尋字串
return place.city.match(reg) || place.state.match(reg)
})
}
function displayMatch() {
// 結果以陣列形式回傳
const matchResult=findMatch(this.value,cities);
// 每一個結果要以li方式呈現
const html= matchResult.map(place=>{
// 符合關鍵字以<span>取代
const regex=new RegExp(this.value,'gi');
const cityName=place.city.replace(regex,`<span class="hl">${this.value}</span>`);
const stateName=place.state.replace(regex,`<span class="hl">${this.value}</span>`)
return `
<li>
<span class="name">${cityName},${stateName}</span>
<span class="population">${place.population}<span>
</li>
`;
}).join('')
suggestions.innerHTML=html;
}
const searchs = document.querySelector('.search')
const suggestions = document.querySelector('.suggestions')
searchs.addEventListener('change', displayMatch);
searchs.addEventListener('keyup', displayMatch);