做者:©liyuechun
簡介:JavaScript30 是 Wes Bos 推出的一個 30 天挑戰。項目免費提供了 30 個視頻教程、30 個挑戰的起始文檔和 30 個挑戰解決方案源代碼。目的是幫助人們用純 JavaScript 來寫東西,不借助框架和庫,也不使用編譯器和引用。如今你看到的是這系列指南的第 6 篇。完整中文版指南及視頻教程在 從零到壹全棧部落。javascript
在輸入框中搜索字或者某個詞
快速匹配含有這個字或者是詞的詩句。css
flex佈局html
nth-child
奇偶匹配html5
linear-gradient
顏色漸變java
transformgit
Fetchgithub
Arrayweb
filter()
正則表達式
map()
json
push()
join()
...
JavaScript RegExp 對象
字面量語法
建立 RegExp 對象的語法
修飾符i
、g
match()
replace()
UI佈局
經過Fetch下載數據
數據處理並保存
事件監聽
數據匹配操做
新數據替換展現
HTML代碼
<form class="search-form"> <input type="text" class="search" placeholder="詩人名字,關鍵字"> <ul class="suggestions"> <li>輸入詞句,找一首詩</li> <li>輸入詞句,找一首詩</li> <li>輸入詞句,找一首詩</li> <li>輸入詞句,找一首詩</li> <li>輸入詞句,找一首詩</li> </ul> </form>
CSS代碼
html { box-sizing: border-box; margin: 0px; background-color: rgb(145, 182, 195); font-family: 'Kaiti', 'SimHei', 'Hiragino Sans GB ', 'helvetica neue'; font-size: 20px; font-weight: 200; } *, *:before, *:after { box-sizing: inherit; } body { display: flex; justify-content: center; } .search-form { max-width: 700px; display: flex; flex-direction: column; justify-content: center; align-items: center; } input.search { padding: 20px; font-family: 'Kaiti', 'helvetica neue'; margin: 0; border: 10px solid #f7f7f7; font-size: 40px; text-align: center; width: 120%; outline: 0; border-radius: 5px; position: relative; top: 10px; left: 10px; 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; top: 7px; width: 100%; } .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; display: flex; flex-direction: column; /*align-items: flex-start;*/ } span.title { margin-right: 20px; text-align: right; color: #7c8e94; margin-top: 5px; } span.hl { color: green; } /*偶數匹配*/ .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%); }
CSS佈局相關參考文檔
const endpoint = 'https://gist.githubusercontent.com/liyuechun/f00bb31fb8f46ee0a283a4d182f691b4/raw/3ea4b427917048cdc596b38b67b5ed664605b76d/TangPoetry.json'; const poetrys = []; fetch(endpoint) .then(blob => { return blob.json(); }) .then(data => { poetrys.push(...data); });
具體數據請求過程見下圖:
blob.json()
是將數據轉換爲json數據,data爲then
函數中轉換完的數據,在這個案例中,data是一個數組。
poetrys.push(...data)
這句代碼中的push
是往數組裏面新增對象,而...data
表明的是將這個data數組中的數據一一的存儲到poetrys
數組中。
const search = document.querySelector('.search'); const suggestions = document.querySelector('.suggestions'); search.addEventListener('change', displayMatches); search.addEventListener('keyup', displayMatches);
獲取search
和suggestions'
節點分別對change
、keyup
事件進行監聽,當輸入框中的內容發生變化或者鍵盤彈起時觸發displayMatches
函數更新數據。
RegExp使用基礎
項目源碼分析
function findMatches(wordToMatch, poetrys) { return poetrys.filter(poet => { // 正則找出匹配的詩句 const regex = new RegExp(wordToMatch, 'gi'); const author = poet.detail_author.join(''); // console.log(author); return poet.detail_text.match(regex) || poet.title.match(regex) || author.match(regex); }); } function displayMatches() { const matches = findMatches(this.value, poetrys); const regex = new RegExp(this.value, 'gi'); const html = matches.map(poet => { // 替換高亮的標籤 const text = poet.detail_text.replace(regex, `<span class="hl">${ this.value }</span>`); const title = poet.title.replace(regex, `<span class="hl">${ this.value }</span>`); const detail_author = poet.detail_author[0].replace(regex, `<span class="hl">${ this.value }</span>`); // 構造 HTML 值 return ` <li> <span class="poet">${ text }</span> <span class="title">${ title } - ${ detail_author }</span> </li> `; }).join(''); // console.log(html); suggestions.innerHTML = html; }
poetrys.filter
會返回帶搜索關鍵字的新數組。
const regex = new RegExp(this.value, 'gi');
表明匹配規則。
g
:執行全局匹配(查找全部匹配而非在找到第一個匹配後中止)。
i
:執行對大小寫不敏感的匹配。
上面的這種寫法等價於:"/this.value/gi"。
matches.map
會返回一個按照新的規則處理完之後的新的數組。
title.replace(regex, "新字符串");
表示將title字符串中知足 regex
規則的字符串替換成新字符串
。
社羣品牌:從零到壹全棧部落
定位:尋找共好,共同窗習,持續輸出全棧技術社羣
業界榮譽:IT界的邏輯思惟
文化:輸出是最好的學習方式
官方公衆號:全棧部落
社羣發起人:春哥(從零到壹創始人,交流微信:liyc1215)
技術交流社區:全棧部落BBS
全棧部落完整系列教程:全棧部落完整電子書學習筆記
關注全棧部落官方公衆號,每晚十點接收系列原創技術推送 |
---|
![]() |