众所周知,搜索引擎是Web开发中比较难的部分。
现在世界上最牛X的搜索引擎绝对是谷歌(Google)无疑了;百度(Baidu)因为符合中国国情加上中国市场成为全球最大的中文搜索引擎;必应(Bing)则在国内知名度不高,不温不火,但我觉得还是挺好用的,至少无广告。
最近看见别人的个人小网站有自己的站内搜索突然羡慕,决定在本网站中也做一个出来。我们没模板,没数据库,纯手打。
大家都应该知道,搜索引擎的原理和核心是爬取和抓取,建立索引。但是我们还没那技术,只是两个无名的大学生开发者而已。
怎么做?思考了很久,我想到了vue,vue可以说是我们网站站内搜索的核心了。
先看效果图:
这就是最终的亚子~虽然有点简陋…
输入搜索内容然后点击搜索或回车,搜索列表会在下面出现,点击即可跳转。
*思路:
—>通过js建立一个函数,把每篇文章的关键词(label)、文章标题(title)和文章链接(url)放进一个数组里,用户输入关键词返回文章的标题(可点击跳转)。再在html页面里引入返回的数据。
*其实这里可以写函数直接检查文章的标题(title),有符合关键字的就返回文章标题(title),不写label也可以。
但我的想法是实现近义词也能搜索出来,所以给数组多加了个标签(label),函数检查标签(label),有符合label的关键字就返回文章标题(title)。
首先我们要先设计基本的布局和样式,这里就不详细说了。CSS样式你们自行想象_
<div class="searchBlock">
<p>站内搜索</p>
<div class="searchBlock-inner">
<form id="main" v-cloak>
<div class="searchBox">
<input id="searchInput" class="col-md-10 col-md-offset-1" type="text" v-model="searchString" placeholder="Hello World !" />
<p id="search_p">搜索</p>
</div>
<ul id="searchList" class="searchList">
<!-- 循环输出数据 -->
<li v-for="article in filteredArticles">
<a target="_blank"><p></p></a>
</li>
</ul>
</form>
</div>
</div>
上面这个想法虽然简单,可是做起来却没那么容易,而且还有点麻烦(因为要把所有文章都放到数组里-_-||)。
上图!
是不是很蠢,本K也觉得~
数据部分我们完成了,接下来就是要通过一个js小小的算法把我们需要的数据返回。
computed: {
// 计算数学,匹配搜索
filteredArticles: function() {
var articles_array = this.articles,
//把articles数组赋值给articles_array对象
searchString = this.searchString;
//把searchString(用户搜索的关键字)赋值给searchString对象
if (!searchString) {
//如果没输入关键字
return articles_array; //返回原来的数组
}
searchString = searchString.trim().toLowerCase();
//trim()的意思为去掉左右两边的空格
//toLowerCase()则是把字符串中的大写转换成小写
articles_array = articles_array.filter(function(item) {
//filter用于接收里面函数的返回结果
if (item.label.toLowerCase().indexOf(searchString) !== -1) {
//确保搜索的字符和已有关键字是子集关系
return item; //返回适配的结果
}
})
if (articles_array == "") { //如果返回的数组为空
document.getElementById("search_p").innerHTML = "未找到该信息!"; //则打印“未找到该信息!”
}
// 返回过来后的数组
return articles_array;
}
}
好了我们有了返回数据,可以直接在html引用!(备注:v-bind它是一个vue指令,用于绑定html属性)
<div class="right col-md-4 hidden-xs hidden-sm" id="right">
<div class="searchBlock">
<p>站内搜索</p>
<div class="searchBlock-inner">
<form id="main" v-cloak>
<div class="searchBox">
<input id="searchInput" class="col-md-10 col-md-offset-1" type="text" v-model="searchString" placeholder="Hello World !" onkeydown="searchEnter()"/>
<p id="search_p" onclick="searchClick()">搜索</p>
</div>
<ul id="searchList" class="searchList">
<!-- 循环输出数据 -->
<li v-for="article in filteredArticles">
<a v-bind:href="article.url" target="_blank"><p>{{article.title}}</p></a>
</li>
</ul>
</form>
<script>search()</script>
</div>
</div>
因为算法中无关键字时是返回整个数组,所以没输入东西时列表(ul)是默认展开的。
要想它关闭,先给它设定个CSS样式display:none,想要展开后面再慢慢调。
我的想法是什么呢?点击“搜索”按钮或回车(enter)展开搜索结果列表(ul),再次点击则关闭列表(回车也一样);还有展开时“搜索”按钮换成“关闭”二字。
想实现这个效果当然还是要用js啦!这里写了两个function就可以咯,由于很简单,这里就不详细讲啦。
function searchClick() {
if (document.getElementById("searchInput").value.length != 0) {
if ($('#searchList').css('display') == 'none') {
$('#searchList').css('display', 'block');
document.getElementById("search_p").innerHTML = "关闭";
} else {
$('#searchList').css('display', 'none');
document.getElementById("search_p").innerHTML = "搜索";
}
} else {
$('#searchList').css('display', 'none');
document.getElementById("search_p").innerHTML = "搜索";
}
}
function searchEnter(event) {
document.onkeydown = function(event) {
if (event.keyCode == 13) {
//回车键的键值为13
searchClick(); //回车需执行的方法
}
};
}
然后遇到一个问题,按回车键后搜索结果列表出现了但是页面会刷新,检查了下发现是html写了表单默认会提交的问题,给表单加个οnsubmit="return false"吧!
<div class="right col-md-4 hidden-xs hidden-sm" id="right">
<div class="searchBlock">
<p>站内搜索</p>
<div class="searchBlock-inner">
<form id="main" v-cloak onsubmit="return false">
<div class="searchBox">
<input id="searchInput" class="col-md-10 col-md-offset-1" type="text" v-model="searchString" placeholder="Hello World !" onkeydown="searchEnter()"/>
<p id="search_p" onclick="searchClick()">搜索</p>
</div>
<ul id="searchList" class="searchList">
<!-- 循环输出数据 -->
<li v-for="article in filteredArticles">
<a v-bind:href="article.url" target="_blank"><p>{{article.title}}</p></a>
</li>
</ul>
</form>
<script>search()</script>
</div>
</div>
本来到这里其实就可以结束的,但是我在自己体验的过程中遇到了一个未完善的地方,发现搜索完不关闭搜索结果列表而把搜索框中的文字全删除的话,整个列表(所有数据,我写的整个数组)就直接显示出来了。这个问题很影响用户体验。所以又改进了一把!
function searchClick() {
if (document.getElementById("searchInput").value.length != 0) {
if ($('#searchList').css('display') == 'none') {
$('#searchList').css('display', 'block');
document.getElementById("search_p").innerHTML = "关闭";
} else {
$('#searchList').css('display', 'none');
document.getElementById("search_p").innerHTML = "搜索";
}
} else {
$('#searchList').css('display', 'none');
document.getElementById("search_p").innerHTML = "搜索";
}
}
function searchEnter(event) {
document.onkeydown = function(event) {
if (event.keyCode == 13) {
//回车键的键值为13
searchClick(); //回车需执行的方法
}
};
$('#searchList').css('display', 'none');
document.getElementById("search_p").innerHTML = "搜索";
}
在这加了两行代码,搜索完删除文字自动display:none,完美解决!
最终的成品就是你现在浏览我们的网站搜索的效果,是不是感觉有点简单粗暴?不过这也算是实现了我们站内的搜索功能了。
想看网页的实现效果可以点击这里
喜欢这篇文章吗?关注我支持一下,分享更多。公众号:Honker