首先到公眾運輸平台找 api
let flights = [];
fetch(flightApi)
.then(blob => {
return blob.json();
})
.then(data => {
flights = data;
});
fetch()是一個可以將 api 給抓下來的方法,更早以前是使用XMLHttpRequest, XMLHttpRequest 可以讓用戶不必重新請求整個網頁,而是只重新渲染其中的一部分
fetch()可以讓我們在索取遠端伺服器的資料同時,去跑接下來的程式碼
非同步的語言在向遠端伺服器要資料的同時
會繼續跑之後的程式碼
所以被稱為非同步
而同步的語言則是一行一行跑程式碼
這會導致在根遠端伺服器請求資料的同時
會一直卡著不動,等到資料請求完畢,才會繼續執行程式碼
這會導致用戶體驗差
而fetch(url)回來的東西會是一個promise
然後使用.then()來取得的資料
.then是promise的一個 method ,在 fetch 取得檔案後要程式做的事情
我們使用第一個.then方法回傳的還是一個promise物件
其內有我們所需要的航班資訊使用.json將之轉成 json 檔
最後再將這些資料(這裡是物件)放到flights array 內
接著我們要來監聽 input 事件, 只要 input 內容有更動就會觸發事件
const searchInput = document.querySelector('.search');
const suggestions = document.querySelector('.suggestions');
searchInput.addEventListener('input', displayMatches);
監聽好後,要來找符合要求的字了,我們要傳出符合要求的「航空公司 ID 」「班機號碼」和「機場 ID 」,但在這之前要先去了解一下正則表達式
之前做的筆記,正則表達式
我們將陣列 flights 用 .filter()篩選,並要符合正則表達式的要求字串才會被 return
match()match()也是 string 的 method,.match(regex)表示字串要符合所規範的正則表達式才會留下
function findMatches(wordToMatch, flights) {
return flights.filter((flight) => {
const regex = new RegExp(wordToMatch, 'gi');
return (`${flight.AirlineID}${flight.FlightNumber}`).match(regex) || flight.ArrivalAirportID.match(regex);
});
};
接著用 matchArr 去裝剛剛成功篩選出的字串,我們希望 match 的字要被 highlight 起來,
所以還要對 matchArr 做修改,得到一個修改過的 Array ,這個描述,就是 .map()。我們要將 match的字用<span class="hl"></span>包起來,這樣就可以吃到 css 特效了。就讓 .replace() 來幫幫我們吧!
function displayMatches() {
const matchArr = findMatches(this.value, flights);
const html = matchArr.map(flight => {
const regex = new RegExp(this.value, 'gi');
const arrivalAirportId = flight.ArrivalAirportID.replace(regex, `<span class="hl">${this.value}</span>`);
const flightNumber = (`${flight.AirlineID}${flight.FlightNumber}`).replace(regex, `<span class="hl">${this.value}</span>`);
const regexT = new RegExp("T", 'gi');
const scheduleDepartureTime = flight.ScheduleDepartureTime === undefined ? "no-data" : flight.ScheduleDepartureTime.replace(regexT, ' ');
return `
<li>
<span class="flight-number">${flightNumber}</span>
<span class="schedule-depar-time">${scheduleDepartureTime}</span>
<span class="airline">${arrivalAirportId}</span>
</li>
`
}).join('');
接著我想要再加個起飛時間!
const scheduleDepartureTime = flight.ScheduleDepartureTime === undefined ? "no-data" : flight.ScheduleDepartureTime.replace(regexT, ' ');
在取得航班表定起飛時間時遇到了一點麻煩
因為並不是每一筆資料都有表定起飛時間
所以如果沒有使用判別式
將會取得兩種資料2018-08-19T09:10和 undefind
這時候如果想要將"T"改成" "會在沒有資料的地方出現問題
因為undefined是不被允許使用replace的
所以我們要講undefined的資料以"no-data"顯示
最後得到的是一個新的 array ,但是 html 看不懂 array ,他只看得懂字串
所以最後我們再使用 .join('') 讓 array 內的每個項目都用''(空字串)串起來,
再使用 innerHTLML 渲染到網頁上