JS 30 是由加拿大的全端工程师 Wes Bos 免费提供的 JavaScript 简单应用课程,课程主打 No Frameworks
、No Compilers
、No Libraries
、No Boilerplate
在30天的30部教学影片里,建立30个JavaScript的有趣小东西。
另外,Wes Bos 也很无私地在 Github 上公开了所有 JS 30 课程的程序码,有兴趣的话可以去 fork 或下载。
利用 Fetch API
取得 JSON
格式的资料,随着输入关键字的不同,将特定资料筛选出来并呈现在网页上。
将要取得的资料来源网址放入 endpoint
中,并建立一个空的city
阵列。
const endpoint = 'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json';
const cities = [];/*empty array*/
fetch()
是 Fetch API
的一个方法,主要用於发出资料的 request
并回传 Promise
,有点类似於XMLHttpRequest
,但在使用上较有弹性。
Promise
物件代表的是一个将要完成或失败的非同步操作,以及它所产生的值。
then()
方法最多需要两个参数,分别作为 Promise
成功和失败时的 callback function
并返回 Promise
。
json()
方法会接收一个 response stream
,在读取完成之後返回一个解析成 JSON
格式的 Promise
。
我们透过 fetch()
向 endpoint
发送 request
,之後将 return 的 Promise
以 json
格式进行解构,最後将这些资料一笔笔的 push 到空的 cities
阵列中。...data
的主要用意在於将原本的 data
阵列中的元素个别拆出来放进 cities
里面,如果直接写cities.push(data)
则 data
会变成在 cities
内部的一个阵列型态元素。
fetch(endpoint)
.then(blob => blob.json())
.then(data => cities.push(...data));
findMatches()
需要用到两个参数,wordToMatch
用来传入要寻找的文字,cities
则是原本的资料阵列,最後回传经过 filter()
过滤後的 cities
阵列。
在 filter()
里,我们将 cities
的每一个元素用 RegExp
物件进行正规表示式的字元比对,之後将包含关键字的 city
或是 state
回传。
RegExp()
用来建立一个正规表达式的物件,wordToMatch
是要进行比对的内容,'gi'
则是 flag,g
代表搜寻出所有符合比对的文字,而不是比对出第一笔就停止,i
代表比对时不分大小写。
function findMatches(wordToMatch, cities){
return cities.filter(place => {
const regex = new RegExp(wordToMatch,'gi');
return place.city.match(regex) || place.state.match(regex);
})
}
numberWithCommas()
主要用来帮我们在每三位数字加上逗号(ex.1,000)。toString()
可以帮我们将 x 转成字串,之後利用 replace()
进行正规表示式的判断并取代字元。
function numberWithCommas(x){
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g,',');
}
宣告 matchArray
并放入找到的结果阵列。接着,将阵列中的元素换成 HTML
的格式。再来宣告一个 Regex
物件,然後宣告两个常数并各自以正规表示式判断并取代(replace)原有的文字内容,改以 HTML
的方式呈现。
之後,透过 Template literals
的格式传回一个<li>...</li>
。最後,使用 join()
将阵列中的所有元素以空字串为分隔,形成一个很长的字串再放入.suggestions
的标签中。
function displayMatches(){
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="ppulation">${numberWithCommas(place.population)}</span>
</li>
`
}).join('');
suggestions.innerHTML = html;
}
分别宣告常数 searchInput
、suggestions
并取得 .search
、.suggestions
标签。最後为搜寻栏(searchInput
) 注册change
和keyup
事件,当栏位数值发生改变或放开键盘的那个刹那都会触发事件,两个事件都是以 displayMatches()
进行事件处理。
const searchInput = document.querySelector('.search');
const suggestions = document.querySelector('.suggestions');
searchInput.addEventListener('change',displayMatches)
searchInput.addEventListener('keyup',displayMatches);
Promise
使用 Fetch
Promise.prototype.then()
Response.json()
Spread syntax (...)
RegExp()
比较 keydown, keypress, keyup 的差异
今天要为各位介绍我们的游戏流程与关卡设定 游戏流程 上图是游戏的流程图,我们的游戏采单一故事线的剧情...
大家好,我是YIYI,今天我要来制做设定页面。 从哪里可以进入设定页面呢? 点击LIST的设定~如下...
今天大概会聊到的范围 Constraint Layout in Compose 上一篇提到,有 R...
我们学习前端语言就是为了跟浏览器沟通,让网页可以渲染出想要的效果,创造使用者互动的良好体验。所以要...
Mac 电脑里有很多重复的图片?有时候我们可能会重复汇入或下载相同的图片却没有及时清理掉。另外,如果...