JS實用案例之輸入智能提示(打字機輸出效果)
前言
本篇文章所有示例來自于??途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ù)報','河南省高校學(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ā)生變化時,調(diào)用suggest函數(shù),用于顯示/隱藏智能提示數(shù)據(jù),參數(shù)items為一個字符串?dāng)?shù)組。
- 當(dāng)items中的字符串和輸入框的值匹配時,將匹配的數(shù)據(jù)依次渲染在ul下的li節(jié)點中,并顯示.js-suggest節(jié)點,否則移除ul下的所有l(wèi)i節(jié)點,并隱藏.js-suggest節(jié)點
- 輸入框的值需要移除兩側(cè)空白再進行匹配
- 輸入框的值為空時,按照全部不匹配處理
- 字符串使用模糊匹配,比如"北大"能匹配"北大"和"北京大學(xué)",但不能匹配"大北京",即按照 /北.*?大.*?/ 這個正則進行匹配
- 通過在.js-suggest節(jié)點上添加/移除 hide 這個class來控制該節(jié)點的隱藏/顯示
JavaScript實現(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)容的正表達式:使用split將字符串轉(zhuǎn)換成數(shù)組 -> 使用map映射生成新數(shù)組 -> 使用join將數(shù)組連接成字符串
const valReg = new RegExp(val.split('').map(v => special(v)).join(''))
// 通過filter方法過濾出items中符合的項:符合的條件是用戶輸入內(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這個class
suggest.classList[item.length ? 'remove' : 'add']('hide')
// 渲染列表
suggest.children[0].innerHTML = item.map(i => `<li>${i}</li>`).join('')
}
// 對特殊字符的處理
function special(val) {
// 如果val是()[].+/?*這類的特殊字符,則在它前面加上轉(zhuǎn)義字符:\
// 為什么是\\${val},兩個\?因為在模板字符串``中\(zhòng)也需要使用\轉(zhuǎn)義
return `${'()[].+/?*'.indexOf(val) === -1 ? val : `\\${val}`}.*?`
}
這個案例中需要注意的地方就是不要忘記對特殊字符的轉(zhuǎn)義(實現(xiàn)special函數(shù))。
知識點:
- RegExp(正則表達式)
- split() 方法使用指定的分隔符字符串將一個String對象分割成子字符串?dāng)?shù)組,以一個指定的分割字串來決定每個拆分的位置。
- map() 方法創(chuàng)建一個新數(shù)組,這個新數(shù)組由原數(shù)組中的每個元素都調(diào)用一次提供的函數(shù)后的返回值組成。
- join() 方法將一個數(shù)組(或一個類數(shù)組對象)的所有元素連接成一個字符串并返回這個字符串。如果數(shù)組只有一個項目,那么將返回該項目而不使用分隔符。
- filter() 方法創(chuàng)建給定數(shù)組一部分的淺拷貝,其包含通過所提供函數(shù)實現(xiàn)的測試的所有元素。
- test() 方法執(zhí)行一個檢索,用來查看正則表達式與指定的字符串是否匹配。返回 true 或 false。
- Element.classList 是一個只讀屬性,返回一個元素 class 屬性的動態(tài) DOMTokenList集合。這可以用于操作 class 集合。
- indexOf() 方法返回在數(shù)組中可以找到給定元素的第一個索引,如果不存在,則返回 -1。
2、打字機輸出
效果演示

有以下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的下劃線閃動節(jié)點,請按照如下需求實現(xiàn) output 函數(shù)
- 函數(shù) output 接收一個字符串參數(shù),每隔200毫秒在閃動節(jié)點之前逐個顯示字符
- 請新建span節(jié)點放置每個字符,其中span必須存在class “word”,并隨機加上 color1 ~ color24 中的任一個class(請使用系統(tǒng)隨機函數(shù))
- 每次輸出指定字符串前,請將閃動節(jié)點之前的所有其他節(jié)點移除
- 不要銷毀或者重新創(chuàng)建閃動節(jié)點
- 如果輸出字符為空格、<、>,請分別對其進行HTML轉(zhuǎn)義,如果是\n請直接輸出<br />,其他字符不需要做處理
- 上面展示的效果為 output('hello world\n你好世界') 之后的界面
JavaScript實現(xiàn)
function output(str) {
const content = document.getElementsByClassName('content')[0]
const jsBlink = document.getElementById('jsBlink')
// 將閃動節(jié)點之前的所有其他節(jié)點移除
while (content.children.length > 0) {
if (content.children[0] == jsBlink) {
// 如果content第1個孩子是jsBlink,說明閃動節(jié)點之前的所有其他節(jié)點移除完畢,則跳出循環(huán)
break;
}
// 刪除content中的指定節(jié)點
content.removeChild(content.children[0]);
}
let i = 0;
const stl = setInterval(() => {
if (str[i] == '\n') {
const br = document.createElement('br')
// 在content中的jsBlink之前插入節(jié)點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) {
// 清除定時器
clearInterval(stl)
}
}, 200)
}
// 調(diào)用測試
output('hello world\n你好世界')
知識點:
Node.insertBefore() 方法在參考節(jié)點之前插入一個擁有指定父節(jié)點的子節(jié)點。
結(jié)語
到此這篇關(guān)于JS實用案例之輸入智能提示的文章就介紹到這了,更多相關(guān)JS輸入智能提示內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JS當(dāng)前頁面登錄注冊框,固定DIV,底層陰影的實例代碼
下面小編就為大家?guī)硪黄狫S當(dāng)前頁面登錄注冊框,固定DIV,底層陰影的實例代碼。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-09-09
layer頁面跳轉(zhuǎn),獲取html子節(jié)點元素的值方法
今天小編就為大家分享一篇layer頁面跳轉(zhuǎn),獲取html子節(jié)點元素的值方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09
JavaScript中輸出</script>標(biāo)簽的方法
這篇文章主要介紹了JavaScript中輸出</script>標(biāo)簽的方法,在一些廣告代碼中經(jīng)常會用到這個小技巧,需要的朋友可以參考下2014-08-08

