不知道大家平常有没有自己空闲的时候写一些小demo的习惯呢?我个人觉得,在空闲的时候时不时写一个小功能,日积月累,当你以后遇到需要使用的时候,就可以直接拿来使用,当然了。业务的需求多变的,多少可能会改一点,不过也一定比从没写过开始写要快得多,本文就介绍一个比较有意思但是也很简单的案例–搜索关键字高亮
1<span>23</span>456
,而后我们对这个 span 标签设置不同的颜色或者其他样式,在显示到页面上,是不是就可以了呢我们先看一下样式布局吧,这个样式布局非常简单,我就只展示显示的效果了,可以自己实现,或者在文章末尾直接复制源码,如图:
现在就是根据我们的分析来具体实现,准备的数据如下:
const data = [
'我们等待着戈多,在等待的过程中发现戈多就是等待本身。--王希明',
'我们登上并非我们所选择的舞台,演出并非我们所选择的剧本。--Enchiridion',
'慢慢来,谁还没有一个努力的过程。--网易云音乐',
'上了陆地的鱼就不能再叫做鱼了。--三体:黑暗森林',
'历史的发展是不以人的意志为转移的。--毛泽东',
'人生天地间,忽如远行客。--古诗十九首',
'甲之蜜糖,乙之砒霜。--曼陀罗',
'回眸一笑百媚生,六宫粉黛无颜色。--长恨歌',
'天之涯,地之角,知交半零落,一壶浊酒尽余欢,今宵别梦寒。--送别',
'荒诞也好,愚笨也好,总会过去的。--一瞬的光和永远'
]
获取 dom,绑定事件如下:
const contentList = document.querySelector('.content-list')
const inp = document.querySelector('.inp')
form.addEventListener('submit', function (e) {
e.preventDefault()
render(data, inp.value)
})
是不是发现了藏在这个事件里面的 render 函数呢?我们的核心就是实现这个函数,这个函数接收两个参数,一个是数据列表,一个是关键词,于是我们可以根据写出 render 函数的函数签名,如下:
function render(list, keyword){
}
然后我们就应该来思考一下,前置条件,在这里,我们明显只有一个条件,那就是有没有关键词,有的话如何,没有的话又如何,首先我们第一步是不是要通过这个有没有关键词进行筛选数据呢?
function render(list, keyword){
let newList = list
if (keyword) {
// 根据关键词输入的筛选数据
newList = list.filter(item => item.includes(keyword))
}
}
在筛选数据的时候,就可以感觉到如果需要往下执行,我们还缺少一个条件,关键词匹配的条件,关键词匹配,我们可以想到什么?是不是正则表达式呢?所以我们还需要定义条件,当有关键词的时候,需要创建一个正则表达式,如下:
function render(list, keyword) {
let newList = list
let reg
if (keyword) {
newList = list.filter(item => item.includes(keyword))
// 创建正则表达式
reg = new RegExp(keyword, 'gi')
}
}
而有了这个筛选后的数据和正则,我们就可以进行真正的渲染了,这个渲染可以手动通过方法创建元素,也可以直接设置 html 字符串,我这里方便演示,就直接使用设置 html 字符串了,如下:
function render(list, keyword) {
let newList = list
let reg
if (keyword) {
newList = list.filter(item => item.includes(keyword))
// 创建正则表达式
reg = new RegExp(keyword, 'gi')
}
contentList.innerHTML = newList.map(item=>{
// 设置默认值
let content = item
// 如果存在有正则表达式存在则表示需要对内容进行关键词匹配
if (reg) {
// 将匹配的关键词通过 replace 方法进行替换-并重新赋值给 content
content = item.replace(reg, `<span class="highlight">${keyword}</span>`)
}
// 返回组装的 html 字符串
return `<div class="item-box">
<p class="item-content">${content}</p>
</div>`
}).join('')
}
这里我们给高亮的 span 的类名定义为 highlight,所以响应的我们需要再 css 文件中定义这样的一个高亮关键词样式,如下:
/* 设置关键词样式 */
.item-content .highlight {
color: #ff4757;
font-weight: bold;
}
我们最后来看一下展示的效果,如图:
这个数据的筛选,是不是需要,可以自己根据自己的需求来设计,这个案例整体是不是还是比较简单呢
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./index.css">
</head>
<body>
<div class="container">
<!-- 搜索 -->
<div class="search-box">
<form id="form">
<input class="inp" autocomplete="off" spellcheck="false" type="text" id="keyword" placeholder="请输入关键字">
<button type="submit" style="display: none;"></button>
</form>
</div>
<!-- 内容列表 -->
<div class="content-list">
</div>
</div>
<script src="./index.js"></script>
</body>
</html>
index.css
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
width: 100vw;
height: 100vh;
overflow: hidden;
padding: 50px;
}
.search-box {
width: 300px;
height: 35px;
border: 1px solid #999;
border-radius: 3px;
margin-bottom: 20px;
}
.search-box input {
all: unset;
padding: 0 5px;
height: 35px;
font-size: 14px;
}
input::placeholder {
color: #ccc;
}
.content-list {
width: 720px;
flex: 1;
overflow: hidden auto;
}
.item-box {
margin-bottom: 10px;
}
.item-content {
color: #130f40;
font-size: 16px;
}
/* 设置关键词样式 */
.item-content .highlight {
color: #ff4757;
font-weight: bold;
}
index.js
const data = [
'我们等待着戈多,在等待的过程中发现戈多就是等待本身。--王希明',
'我们登上并非我们所选择的舞台,演出并非我们所选择的剧本。--Enchiridion',
'慢慢来,谁还没有一个努力的过程。--网易云音乐',
'上了陆地的鱼就不能再叫做鱼了。--三体:黑暗森林',
'历史的发展是不以人的意志为转移的。--毛泽东',
'人生天地间,忽如远行客。--古诗十九首',
'甲之蜜糖,乙之砒霜。--曼陀罗',
'回眸一笑百媚生,六宫粉黛无颜色。--长恨歌',
'天之涯,地之角,知交半零落,一壶浊酒尽余欢,今宵别梦寒。--送别',
'荒诞也好,愚笨也好,总会过去的。--一瞬的光和永远'
]
const contentList = document.querySelector('.content-list')
const inp = document.querySelector('.inp')
form.addEventListener('submit', function (e) {
e.preventDefault()
render(data, inp.value)
})
function render(list, keyword) {
let newList = list
let reg
if (keyword) {
newList = list.filter(item => item.includes(keyword))
reg = new RegExp(keyword, 'gi')
}
contentList.innerHTML = newList
.map(item => {
let content = item
if (reg) {
content = item.replace(reg, `<span class="highlight">${keyword}</span>`)
}
return `<div class="item-box">
<p class="item-content">${content}</p>
</div>`
})
.join('')
}
render(data, '')