JS实用案例之输入智能提示(打字机输出效果)
海底烧烤店ai 人气:0前言
本篇文章所有示例来自于牛客网题库/在线编程/JS篇,这些都是前端开发中常用的功能,借此记录一下刷题过程,巩固基础!
1、输入智能提示
效果演示
有以下HTML
和CSS
:
HTML结构
<div class="search"> <div> <!-- 调用suggest函数 --> <input type="text" class="js-input" oninput="suggest(['河南加入下雪群聊','河南疫情','河南大学','河南疫情最新消息','河南地图','河南卫视重阳奇妙游2022节目单','河南天气预报','河南省高校学生资助在线'])"> </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; }
案例需求
- 当输入框的值发生变化时,调用suggest函数,用于显示/隐藏智能提示数据,参数items为一个字符串数组。
- 当items中的字符串和输入框的值匹配时,将匹配的数据依次渲染在ul下的li节点中,并显示.js-suggest节点,否则移除ul下的所有li节点,并隐藏.js-suggest节点
- 输入框的值需要移除两侧空白再进行匹配
- 输入框的值为空时,按照全部不匹配处理
- 字符串使用模糊匹配,比如"北大"能匹配"北大"和"北京大学",但不能匹配"大北京",即按照 /北.*?大.*?/ 这个正则进行匹配
- 通过在.js-suggest节点上添加/移除 hide 这个class来控制该节点的隐藏/显示
JavaScript实现
function suggest(items) { const val = document.getElementsByClassName('js-input')[0].value.trim() const suggest = document.getElementsByClassName('js-suggest')[0] // 创建输入内容的正表达式:使用split将字符串转换成数组 -> 使用map映射生成新数组 -> 使用join将数组连接成字符串 const valReg = new RegExp(val.split('').map(v => special(v)).join('')) // 通过filter方法过滤出items中符合的项:符合的条件是用户输入内容不为空(val != '')并且与用户输入的内容匹配 const item = items.filter(i => val != '' && valReg.test(i)) // 如果item.length不为0,代表有匹配的数据,则执行: // suggest.classList['remove']('hide')相当于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是()[].+/?*这类的特殊字符,则在它前面加上转义字符:\ // 为什么是\\${val},两个\?因为在模板字符串``中\也需要使用\转义 return `${'()[].+/?*'.indexOf(val) === -1 ? val : `\\${val}`}.*?` }
这个案例中需要注意的地方就是不要忘记对特殊字符的转义(实现special
函数)。
知识点:
- RegExp(正则表达式)
- split() 方法使用指定的分隔符字符串将一个String对象分割成子字符串数组,以一个指定的分割字串来决定每个拆分的位置。
- map() 方法创建一个新数组,这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成。
- join() 方法将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。如果数组只有一个项目,那么将返回该项目而不使用分隔符。
- filter() 方法创建给定数组一部分的浅拷贝,其包含通过所提供函数实现的测试的所有元素。
- test() 方法执行一个检索,用来查看正则表达式与指定的字符串是否匹配。返回 true 或 false。
- Element.classList 是一个只读属性,返回一个元素 class 属性的动态 DOMTokenList集合。这可以用于操作 class 集合。
- indexOf() 方法返回在数组中可以找到给定元素的第一个索引,如果不存在,则返回 -1。
2、打字机输出
效果演示
有以下HTML
和CSS
:
HTML结构
<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
的下划线闪动节点,请按照如下需求实现 output
函数
- 函数 output 接收一个字符串参数,每隔200毫秒在闪动节点之前逐个显示字符
- 请新建span节点放置每个字符,其中span必须存在class “word”,并随机加上 color1 ~ color24 中的任一个class(请使用系统随机函数)
- 每次输出指定字符串前,请将闪动节点之前的所有其他节点移除
- 不要销毁或者重新创建闪动节点
- 如果输出字符为空格、<、>,请分别对其进行HTML转义,如果是\n请直接输出<br />,其他字符不需要做处理
- 上面展示的效果为 output('hello world\n你好世界') 之后的界面
JavaScript实现
function output(str) { const content = document.getElementsByClassName('content')[0] const jsBlink = document.getElementById('jsBlink') // 将闪动节点之前的所有其他节点移除 while (content.children.length > 0) { if (content.children[0] == jsBlink) { // 如果content第1个孩子是jsBlink,说明闪动节点之前的所有其他节点移除完毕,则跳出循环 break; } // 删除content中的指定节点 content.removeChild(content.children[0]); } let i = 0; const stl = setInterval(() => { if (str[i] == '\n') { const br = document.createElement('br') // 在content中的jsBlink之前插入节点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) } // 调用测试 output('hello world\n你好世界')
知识点:
Node.insertBefore() 方法在参考节点之前插入一个拥有指定父节点的子节点。
结语
加载全部内容