這次的內容是,當我們在搜索欄打字母,會篩選出相應的城市名稱,達到搜尋篩選的效果
實做連結
const suggestions = document.querySelector(".suggestions");
const search = document.querySelector(".search");
// 當鍵盤keyup時
search.addEventListener("keyup", displayMatches);
search.addEventListener("change", displayMatches);
我們在監聽的時候主要是監聽keyup
以及change
事件
keyup
keyup
事件都會觸發。所以我們要額外增加監聽事件change
,change
能捕捉到通過剪貼板粘貼文本、使用語音輸入、更改選項列表中的值等方式進行的輸入變化,正好可以補齊keyup
的缺失。
let cities = [];
//取得城市的資料
const endpoint = fetch(
"https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json"
);
endpoint
.then((res) => res.json())
.then((data) => {
cities.push(...data);
});
我們要透過json文件去抓取我們的資料,要取得endpoint的資料需要利用json()
去讀取並解析數據,當取得後數據會傳遞給下一個 then 方法。 data 是一個包含所有城市和州信息的數組。cities.push(...data)
使用展開運算符(...)將 data 數組中的所有元素逐個插入到 cities 數組中。
當我們去console.log(cities)
時可以看到陣列裡包裹著許多物件資料,把[0]物件展開來看會出現以下的內容:
{city: "New York"
growth_from_2000_to_2013: "4.8%"
latitude: 40.7127837
longitude: -74.0059413
population: "8405837"
rank: "1"
state: "New York"}
function findMatches(wordToMatch, cities) {
return cities.filter((place) => {
const regex = new RegExp(wordToMatch, "gi");
return place.city.match(regex) || place.state.match(regex);
});
}
使用 filter()
來篩選符合條件的城市
創建一個正則表達式,參數為 wordToMatch,gi 表示全局搜索且忽略大小寫,
使用 match()
來檢查cities每個子元素的屬性city 或 state其一是否與正則表達式匹配
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
這段是用來處理,cities中的population屬性,我們利用正則表達式將一個數字格式化,在數字串中的每個千位位置添加逗點","符號,使字串從1234567轉為1,234,567
function displayMatches() {
const matchArray = findMatches(this.value, cities);
const html = matchArray
.map((place) => {
// 將城市名和州名中與搜索關鍵字匹配的部分用 <span class="hl"> 包裹起來做出提亮效果
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">${numberWithCommas(
place.population //取被篩選過後cities的.population元素
)}</span>
</li>
`;
})
.join("");
suggestions.innerHTML = html;
}
matchArray
內的findMatches(this.value)
為當我們在搜索欄打字時取得的值,帶入函式內便可以比對我們輸入的值
以及cities
是否有對應的城市或州,並且篩選為一個陣列
place.city.replace
找到與place.city對應的regex詞彙並轉換成<span class="hl">${this.value}</span>
做出字體提亮效果
suggestions.innerHTML=html
將我們取得的資料顯示在網頁上
obj.replace(a,b) replace
可以用來尋找arr中與a相應的字串並替換成的內容Fetch API:
使用 fetch() 從遠程服務器請求數據。fetch() 返回一個 Promise,可以通過 .then() 方法鏈式調用來處理響應數據。正則表達式 (RegExp):
正則表達式被用來進行字符串匹配。在此內容,input輸入的字串被轉換為一個正則表達式,用來篩選城市或州名中是否包含這個搜索詞。 new RegExp(wordToMatch, "gi") 中的 "gi" 表示全局匹配並忽略大小寫。JS30
[ Alex 宅幹嘛 ] 👨💻 深入淺出 Javascript30 快速導覽:Day 6:Type Ahead