JS實(shí)用案例之輸入智能提示(打字機(jī)輸出效果)
前言
本篇文章所有示例來自于??途W(wǎng)題庫/在線編程/JS篇,這些都是前端開發(fā)中常用的功能,借此記錄一下刷題過程,鞏固基礎(chǔ)!
1、輸入智能提示
效果演示
有以下HTML
和CSS
:
HTML結(jié)構(gòu)
<div class="search"> <div> <!-- 調(diào)用suggest函數(shù) --> <input type="text" class="js-input" oninput="suggest(['河南加入下雪群聊','河南疫情','河南大學(xué)','河南疫情最新消息','河南地圖','河南衛(wèi)視重陽奇妙游2022節(jié)目單','河南天氣預(yù)報(bào)','河南省高校學(xué)生資助在線'])"> </div> <div class="js-suggest"> <ul></ul> </div> </div>
CSS樣式
.search { position: relative; } .js-input { width: 450px; height: 22px; line-height: 22px; font-size: 16px; padding: 8px; border: 1px solid #cccccc; outline: none; } .js-suggest { width: 466px; font-size: 14px; border: 1px solid #cccccc; background: #ffffff; position: absolute; left: 0; top: 39px; } .js-suggest.hide { display: none; } .js-suggest ul { display: block; list-style: none; padding: 0; margin: 0; } .js-suggest ul li { color: #000; font: 14px arial; line-height: 25px; padding: 0 8px; position: relative; cursor: default; } .js-suggest ul li:hover { background: #f0f0f0; }
案例需求
- 當(dāng)輸入框的值發(fā)生變化時(shí),調(diào)用suggest函數(shù),用于顯示/隱藏智能提示數(shù)據(jù),參數(shù)items為一個(gè)字符串?dāng)?shù)組。
- 當(dāng)items中的字符串和輸入框的值匹配時(shí),將匹配的數(shù)據(jù)依次渲染在ul下的li節(jié)點(diǎn)中,并顯示.js-suggest節(jié)點(diǎn),否則移除ul下的所有l(wèi)i節(jié)點(diǎn),并隱藏.js-suggest節(jié)點(diǎn)
- 輸入框的值需要移除兩側(cè)空白再進(jìn)行匹配
- 輸入框的值為空時(shí),按照全部不匹配處理
- 字符串使用模糊匹配,比如"北大"能匹配"北大"和"北京大學(xué)",但不能匹配"大北京",即按照 /北.*?大.*?/ 這個(gè)正則進(jìn)行匹配
- 通過在.js-suggest節(jié)點(diǎn)上添加/移除 hide 這個(gè)class來控制該節(jié)點(diǎn)的隱藏/顯示
JavaScript實(shí)現(xiàn)
function suggest(items) { const val = document.getElementsByClassName('js-input')[0].value.trim() const suggest = document.getElementsByClassName('js-suggest')[0] // 創(chuàng)建輸入內(nèi)容的正表達(dá)式:使用split將字符串轉(zhuǎn)換成數(shù)組 -> 使用map映射生成新數(shù)組 -> 使用join將數(shù)組連接成字符串 const valReg = new RegExp(val.split('').map(v => special(v)).join('')) // 通過filter方法過濾出items中符合的項(xiàng):符合的條件是用戶輸入內(nèi)容不為空(val != '')并且與用戶輸入的內(nèi)容匹配 const item = items.filter(i => val != '' && valReg.test(i)) // 如果item.length不為0,代表有匹配的數(shù)據(jù),則執(zhí)行: // suggest.classList['remove']('hide')相當(dāng)于suggest.classList.remove('hide') 效果是刪除hide這個(gè)class suggest.classList[item.length ? 'remove' : 'add']('hide') // 渲染列表 suggest.children[0].innerHTML = item.map(i => `<li>${i}</li>`).join('') } // 對(duì)特殊字符的處理 function special(val) { // 如果val是()[].+/?*這類的特殊字符,則在它前面加上轉(zhuǎn)義字符:\ // 為什么是\\${val},兩個(gè)\?因?yàn)樵谀0遄址甡`中\(zhòng)也需要使用\轉(zhuǎn)義 return `${'()[].+/?*'.indexOf(val) === -1 ? val : `\\${val}`}.*?` }
這個(gè)案例中需要注意的地方就是不要忘記對(duì)特殊字符的轉(zhuǎn)義(實(shí)現(xiàn)special
函數(shù))。
知識(shí)點(diǎn):
- RegExp(正則表達(dá)式)
- split() 方法使用指定的分隔符字符串將一個(gè)String對(duì)象分割成子字符串?dāng)?shù)組,以一個(gè)指定的分割字串來決定每個(gè)拆分的位置。
- map() 方法創(chuàng)建一個(gè)新數(shù)組,這個(gè)新數(shù)組由原數(shù)組中的每個(gè)元素都調(diào)用一次提供的函數(shù)后的返回值組成。
- join() 方法將一個(gè)數(shù)組(或一個(gè)類數(shù)組對(duì)象)的所有元素連接成一個(gè)字符串并返回這個(gè)字符串。如果數(shù)組只有一個(gè)項(xiàng)目,那么將返回該項(xiàng)目而不使用分隔符。
- filter() 方法創(chuàng)建給定數(shù)組一部分的淺拷貝,其包含通過所提供函數(shù)實(shí)現(xiàn)的測(cè)試的所有元素。
- test() 方法執(zhí)行一個(gè)檢索,用來查看正則表達(dá)式與指定的字符串是否匹配。返回 true 或 false。
- Element.classList 是一個(gè)只讀屬性,返回一個(gè)元素 class 屬性的動(dòng)態(tài) DOMTokenList集合。這可以用于操作 class 集合。
- indexOf() 方法返回在數(shù)組中可以找到給定元素的第一個(gè)索引,如果不存在,則返回 -1。
2、打字機(jī)輸出
效果演示
有以下HTML
和CSS
:
HTML結(jié)構(gòu)
<div class="content"> <span class="word color23">h</span> <span class="word color22">e</span> <span class="word color4">l</span> <span class="word color24">l</span> <span class="word color17">o</span> <span class="word color2"> </span> <span class="word color9">w</span> <span class="word color3">o</span> <span class="word color1">r</span> <span class="word color23">l</span> <span class="word color15">d</span> <br> <span class="word color15">你</span> <span class="word color13">好</span> <span class="word color16">世</span> <span class="word color19">界</span> <span class="blink" id="jsBlink">|</span> </div>
CSS樣式
html, body { margin: 0; } .color1 { color: #E60012; } .color2 { color: #EB6100; } .color3 { color: #F39800; } .color4 { color: #FCC800; } .color5 { color: #FFF100; } .color6 { color: #CFDB00; } .color7 { color: #8FC31F; } .color8 { color: #22AC38; } .color9 { color: #009944; } .color10 { color: #009B6B; } .color11 { color: #009E96; } .color12 { color: #00A0C1; } .color13 { color: #00A0E9; } .color14 { color: #0086D1; } .color15 { color: #0068B7; } .color16 { color: #00479D; } .color17 { color: #1D2088; } .color18 { color: #601986; } .color19 { color: #920783; } .color20 { color: #BE0081; } .color21 { color: #E4007F; } .color22 { color: #E5006A; } .color23 { color: #E5004F; } .color24 { color: #E60033; } .word { font-size: 20px; } .content { text-align: center; font-size: 0; } .blink { font-size: 20px; animation: fade 500ms infinite; -webkit-animation: fade 500ms infinite; } @keyframes fade { from { opacity: 1.0; } 50% { opacity: 0; } to { opacity: 1.0; } }
案例需求
頁面上存在id
為jsBlink
的下劃線閃動(dòng)節(jié)點(diǎn),請(qǐng)按照如下需求實(shí)現(xiàn) output
函數(shù)
- 函數(shù) output 接收一個(gè)字符串參數(shù),每隔200毫秒在閃動(dòng)節(jié)點(diǎn)之前逐個(gè)顯示字符
- 請(qǐng)新建span節(jié)點(diǎn)放置每個(gè)字符,其中span必須存在class “word”,并隨機(jī)加上 color1 ~ color24 中的任一個(gè)class(請(qǐng)使用系統(tǒng)隨機(jī)函數(shù))
- 每次輸出指定字符串前,請(qǐng)將閃動(dòng)節(jié)點(diǎn)之前的所有其他節(jié)點(diǎn)移除
- 不要銷毀或者重新創(chuàng)建閃動(dòng)節(jié)點(diǎn)
- 如果輸出字符為空格、<、>,請(qǐng)分別對(duì)其進(jìn)行HTML轉(zhuǎn)義,如果是\n請(qǐng)直接輸出<br />,其他字符不需要做處理
- 上面展示的效果為 output('hello world\n你好世界') 之后的界面
JavaScript實(shí)現(xiàn)
function output(str) { const content = document.getElementsByClassName('content')[0] const jsBlink = document.getElementById('jsBlink') // 將閃動(dòng)節(jié)點(diǎn)之前的所有其他節(jié)點(diǎn)移除 while (content.children.length > 0) { if (content.children[0] == jsBlink) { // 如果content第1個(gè)孩子是jsBlink,說明閃動(dòng)節(jié)點(diǎn)之前的所有其他節(jié)點(diǎn)移除完畢,則跳出循環(huán) break; } // 刪除content中的指定節(jié)點(diǎn) content.removeChild(content.children[0]); } let i = 0; const stl = setInterval(() => { if (str[i] == '\n') { const br = document.createElement('br') // 在content中的jsBlink之前插入節(jié)點(diǎn)br content.insertBefore(br, jsBlink) } else { const span = document.createElement('span') span.classList.add('word') span.classList.add(`color${Math.floor(Math.random() * 24 + 1)}`) switch (str[i]) { case ' ': span.innerHTML = ' ' break; case '<': span.innerHTML = '<' break; case '>': span.innerHTML = '>' break; default: span.innerHTML = str[i] break; } content.insertBefore(span, jsBlink) } i++; if (i >= str.length) { // 清除定時(shí)器 clearInterval(stl) } }, 200) } // 調(diào)用測(cè)試 output('hello world\n你好世界')
知識(shí)點(diǎn):
Node.insertBefore() 方法在參考節(jié)點(diǎn)之前插入一個(gè)擁有指定父節(jié)點(diǎn)的子節(jié)點(diǎn)。
結(jié)語
到此這篇關(guān)于JS實(shí)用案例之輸入智能提示的文章就介紹到這了,更多相關(guān)JS輸入智能提示內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JS 判斷undefined的實(shí)現(xiàn)代碼
JS中如何判斷undefined2009-11-11js獲取圖片base64的正確實(shí)現(xiàn)方式
這篇文章主要給大家介紹了關(guān)于js獲取圖片base64的正確實(shí)現(xiàn)方式,BLOB是二進(jìn)制大對(duì)象,是一個(gè)可以存儲(chǔ)二進(jìn)制文件的容器,?在計(jì)算機(jī)中BLOB常常是數(shù)據(jù)庫中用來存儲(chǔ)二進(jìn)制文件的字段類型,需要的朋友可以參考下2024-01-01JavaScript實(shí)現(xiàn)拖拽排序的方法詳解
可拖拽排序的菜單效果大家想必都很熟悉,本次我們通過一個(gè)可拖拽排序的九宮格案例來演示其實(shí)現(xiàn)原理,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2022-05-05JS當(dāng)前頁面登錄注冊(cè)框,固定DIV,底層陰影的實(shí)例代碼
下面小編就為大家?guī)硪黄狫S當(dāng)前頁面登錄注冊(cè)框,固定DIV,底層陰影的實(shí)例代碼。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-09-09JavaScript實(shí)現(xiàn)煙花綻放動(dòng)畫效果
這篇文章主要介紹了JavaScript如何實(shí)現(xiàn)煙花綻放動(dòng)畫效果,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-08-08layer頁面跳轉(zhuǎn),獲取html子節(jié)點(diǎn)元素的值方法
今天小編就為大家分享一篇layer頁面跳轉(zhuǎn),獲取html子節(jié)點(diǎn)元素的值方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-09-09JavaScript中輸出</script>標(biāo)簽的方法
這篇文章主要介紹了JavaScript中輸出</script>標(biāo)簽的方法,在一些廣告代碼中經(jīng)常會(huì)用到這個(gè)小技巧,需要的朋友可以參考下2014-08-08