俗話說的好,一天一蘋果,醫生遠離我
一天一 JS,What the f*ck JavaScript?
small steps every day - 記錄著新手村日記
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Type Ahead ?</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<form class="search-form">
<input type="text" class="search" placeholder="City or State">
<ul class="suggestions">
<li>Filter for a city</li>
<li>or a state</li>
</ul>
</form>
<script>
const endpoint = 'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json';
</script>
</body>
</html>
/* style.css */
html {
box-sizing: border-box;
background: #ffc600;
font-family: 'helvetica neue';
font-size: 20px;
font-weight: 200;
}
*, *:before, *:after {
box-sizing: inherit;
}
input {
width: 100%;
padding: 20px;
}
.search-form {
max-width: 400px;
margin: 50px auto;
}
input.search {
margin: 0;
text-align: center;
outline: 0;
border: 10px solid #F7F7F7;
width: 120%;
left: -10%;
position: relative;
top: 10px;
z-index: 2;
border-radius: 5px;
font-size: 40px;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.12), inset 0 0 2px rgba(0, 0, 0, 0.19);
}
.suggestions {
margin: 0;
padding: 0;
position: relative;
/*perspective: 20px;*/
}
.suggestions li {
background: white;
list-style: none;
border-bottom: 1px solid #D8D8D8;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.14);
margin: 0;
padding: 20px;
transition: background 0.2s;
display: flex;
justify-content: space-between;
text-transform: capitalize;
}
.suggestions li:nth-child(even) {
transform: perspective(100px) rotateX(3deg) translateY(2px) scale(1.001);
background: linear-gradient(to bottom, #ffffff 0%,#EFEFEF 100%);
}
.suggestions li:nth-child(odd) {
transform: perspective(100px) rotateX(-3deg) translateY(3px);
background: linear-gradient(to top, #ffffff 0%,#EFEFEF 100%);
}
span.population {
font-size: 15px;
}
.hl {
background: #ffc600;
}
首先,先來學一下如何抓 Json 檔吧!不知道大家習慣用這種舊式的寫法還是新的 ES6 語法 cities
宣告為 const 並設為空陣列,並再底下將 return 回來的結果 ...拆開 push
回來呢?我是比較喜歡舊的下面這種寫法啦w
Using Fetch:https://ubin.io/cz5PZD
<script>
const endpoint = 'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json';
let cities = null
fetch(endpoint)
.then(function(blog){
return blog.json()
})
.then(function(myJson){
return cities = myJson
})
</script>
瀏覽器 console 看看有沒有抓到:
// cities
// (1000) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, …]
使用者在輸入 City or State 放開按鍵的時候,搜尋與Json的資料有哪幾筆符合?這邊我們必須透過正則RegExp 來寫,此外也來批純的方法xd
<script>
// 略
let cities = null
fetch(endpoint)
.then(function(blog){
return blog.json()
})
.then(function(myJson){
return cities = myJson
})
document.querySelector('.search').addEventListener("keyup", keyupHandler)
function keyupHandler(){
}
</script>
在 pure function findMatches
中,wordToMatch 與 cities 兩個值不會變動,透過正則將 wordToMatch
丟進來,後面 'gi' 裡的 g 代表全部的意思、i 代表不分大小寫,再回資料結構中有 city || state 回傳值...
RegExp:https://ubin.io/pjvYgJ
Pure function:https://ubin.io/RpbKDT
<script>
// 上略
document.querySelector('.search').addEventListener("keyup", keyupHandler)
function keyupHandler(){
const matchArray = findMatches(this.value, cities)
console.log(matchArray)
}
function findMatches(wordToMatch, cities) {
return cities.filter(function(place){
const regex = new RegExp(wordToMatch, 'gi')
return place.city.match(regex) || place.state.match(regex)
})
}
</script>
接著來處理 DOM 的資料,並新增抓到的資料透過來新增HTML 到 Class .suggestions
裡,這邊單純只是做資料的處理,可能會看不懂的地方是,以前用單引號表示字串在 ES6 中換成蝌蚪按鍵的一點符號(這個該叫什麼好呢xd ),另一個為 numberWithCommas
方法中的 toLocaleString()
,在原作者中是用正則去做處理,不過感覺用這個會比較直接...
Number.prototype.toLocaleString():https://reurl.cc/NaXNde
<script>
// 上略
function keyupHandler(){
const matchArray = findMatches(this.value, cities)
const html = matchArray.map(place => {
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)}</span>
</li>
`
}).join('')
document.querySelector('.suggestions').innerHTML = html
}
function numberWithCommas(x) {
return x.toLocaleString()
}
</script>
就大功告成啦!
<script>
const endpoint = 'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json';
let cities = null
fetch(endpoint)
.then(function(blog){
return blog.json()
})
.then(function(myJson){
return cities = myJson
})
document.querySelector('.search').addEventListener("keyup", keyupHandler)
function keyupHandler(){
const matchArray = findMatches(this.value, cities)
const html = matchArray.map(place => {
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)}</span>
</li>
`
}).join('')
document.querySelector('.suggestions').innerHTML = html
}
function numberWithCommas(x) {
return x.toLocaleString()
}
function findMatches(wordToMatch, cities) {
return cities.filter(function(place){
const regex = new RegExp(wordToMatch, 'gi')
return place.city.match(regex) || place.state.match(regex)
})
}
</script>
本刊同步於個人網站:http://chestertang.site/
本次範例程式碼原作者來源:https://reurl.cc/yynKGl