站内搜索功能完成

This commit is contained in:
结发受长生 2018-05-08 18:39:35 +08:00
parent 04442faf3d
commit ff62d72b4f
4 changed files with 33 additions and 121 deletions

View File

@ -17,8 +17,8 @@ timezone:
# URL # URL
## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/' ## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/'
# url: https://www.colorfulsweet.site url: https://www.colorfulsweet.site
url: http://localhost:6603 # url: http://localhost:6603
root: / root: /
permalink: :title/ permalink: :title/
permalink_defaults: permalink_defaults:

View File

@ -23,9 +23,14 @@
<div class="input-box"><input type="text" id="search-input" v-model="queryText" placeholder="站内搜索"/></div> <div class="input-box"><input type="text" id="search-input" v-model="queryText" placeholder="站内搜索"/></div>
<!-- 搜索结果区 --> <!-- 搜索结果区 -->
<div id="search-result-box" v-show="queryText"> <div id="search-result-box" v-show="queryText">
<div v-html="searchResult"></div> <ul class="search-result-list" v-if="searchResult.length">
<!-- 无匹配时显示 --> <li v-for="(article,index) in searchResult" :key="index">
<p class="no-result" v-if="!searchResult">没有搜索到任何结果</p> <a :href='article.url' class='search-result-title' target='_blank'>{{article.title}}</a>
<p class="search-result" v-html="article.matchContent"></p>
</li>
</ul>
<!-- 无匹配时显示 -->
<p class="search-result" v-else>没有搜索到任何结果</p>
</div> </div>
</div> </div>
<div class="profile clearfix"> <div class="profile clearfix">

View File

@ -55,7 +55,10 @@
margin-top 0 margin-top 0
a.search-result-title a.search-result-title
color #3272b5 color #3272b5
font-size 20px font-size 18px
p.search-result
font-size 14px
margin 0.6em 0
strong.search-keyword strong.search-keyword
color #ff776d color #ff776d
.logo .logo

View File

@ -1,103 +1,10 @@
// A local search script with the help of [hexo-generator-search](https://github.com/PaicHyperionDev/hexo-generator-search)
// Copyright (C) 2015
// Joseph Pan <http://github.com/wzpan>
// Shuhao Mao <http://github.com/maoshuhao>
// Edited by MOxFIVE <http://github.com/MOxFIVE>
(function(){ (function(){
var searchFunc = function(path, search_id, content_id) {
'use strict';
axios({
url: path
}).then(function(response){
var parser = new DOMParser()
const xmlDoms = parser.parseFromString(response.data, "application/xml")
//找出所有文章的标题 正文 URL
var datas = Array.prototype.map.call(xmlDoms.getElementsByTagName("entry"), function(){
return {
title: this.getElementsByTagName("title").innerHTML,
content: this.getElementsByTagName("content").innerHTML,
url: this.getElementsByTagName("url").innerHTML,
}
})
var $input = document.getElementById(search_id);
var $resultContent = document.getElementById(content_id);
$input.addEventListener('input', function(){
var str='<ul class=\"search-result-list\">';
var keywords = this.value.trim().toLowerCase().split(/[\s\-]+/);
$resultContent.innerHTML = "";
if (this.value.trim().length <= 0) {
return;
}
// perform local searching
datas.forEach(function(data) {
var isMatch = true;
var content_index = [];
var data_title = data.title.trim().toLowerCase();
var data_content = data.content.trim().replace(/<[^>]+>/g,"").toLowerCase();
var data_url = data.url;
var index_title = -1;
var index_content = -1;
var first_occur = -1;
// only match artiles with not empty titles and contents
if(data_title != '' && data_content != '') {
keywords.forEach(function(keyword, i) {
index_title = data_title.indexOf(keyword);
index_content = data_content.indexOf(keyword);
if( index_title < 0 && index_content < 0 ){
isMatch = false;
} else {
if (index_content < 0) {
index_content = 0;
}
if (i == 0) {
first_occur = index_content;
}
}
});
}
// show search results
if (isMatch) {
str += "<li><a href='"+ data_url +"' class='search-result-title' target='_blank'>"+ "> " + data_title +"</a>";
var content = data.content.trim().replace(/<[^>]+>/g,"");
if (first_occur >= 0) {
// cut out characters
var start = first_occur - 6;
var end = first_occur + 6;
if(start < 0){
start = 0;
}
if(start == 0){
end = 10;
}
if(end > content.length){
end = content.length;
}
var match_content = content.substr(start, end);
// highlight all keywords
keywords.forEach(function(keyword){
var regS = new RegExp(keyword, "gi");
match_content = match_content.replace(regS, "<em class=\"search-keyword\">"+keyword+"</em>");
})
str += "<p class=\"search-result\">" + match_content +"...</p>"
}
}
})
$resultContent.innerHTML = str;
})
})
// $.ajax({
// url: path,
// dataType: "xml",
// })
}
var articleDatas = null; var articleDatas = null;
new Vue({ new Vue({
el: "#search-box", el: "#search-box",
data: { data: {
queryText: null, queryText: null,
searchResult: null searchResult: []
}, },
mounted: function() { mounted: function() {
axios({ axios({
@ -124,22 +31,21 @@ new Vue({
}, },
watch: { watch: {
queryText: function(newVal, oldVal) { queryText: function(newVal, oldVal) {
this.searchResult.length = 0;
if(!newVal || !newVal.trim() || !articleDatas) return if(!newVal || !newVal.trim() || !articleDatas) return
var keywords = newVal.trim().toLowerCase().split(/[\s\-]+/); var keywords = newVal.trim().toLowerCase().split(/[\s\-]+/);
var searchResult = '<ul class=\"search-result-list\">'; var _this = this;
articleDatas.forEach(function(article){ articleDatas.forEach(function(article){
var isMatch = true; var isMatch = true;
var content_index = []; var title = article.title.trim().toLowerCase();
var data_title = article.title.trim().toLowerCase(); var content = article.content.trim().replace(/<[^>]+>/g,"").toLowerCase();
var data_content = article.content.trim().replace(/<[^>]+>/g,"").toLowerCase();
var data_url = article.url;
var index_title = -1; var index_title = -1;
var index_content = -1; var index_content = -1;
var first_occur = -1; var first_occur = -1; //关键字在正文当中第一次出现的位置
if(data_title && data_content) { if(title && content) {
keywords.forEach(function(keyword, i) { keywords.forEach(function(keyword, i) {
index_title = data_title.indexOf(keyword); index_title = title.indexOf(keyword);
index_content = data_content.indexOf(keyword); index_content = content.indexOf(keyword);
if( index_title < 0 && index_content < 0 ){ if( index_title < 0 && index_content < 0 ){
isMatch = false; isMatch = false;
} else { } else {
@ -153,13 +59,13 @@ new Vue({
}); });
} }
if (isMatch) { if (isMatch) {
searchResult += "<li><a href='"+ data_url + var resultItem = {};
"' class='search-result-title' target='_blank'>"+ "> " +data_title+"</a>"; resultItem.url = article.url;
var content = article.content.trim().replace(/<[^>]+>/g,""); resultItem.title = article.title;
if (first_occur >= 0) { if (first_occur >= 0) {
// cut out characters // cut out characters
var start = first_occur - 6; var start = first_occur - 6;
var end = first_occur + 6; var end = first_occur + 15;
if(start < 0){ if(start < 0){
start = 0; start = 0;
} }
@ -169,20 +75,18 @@ new Vue({
if(end > content.length){ if(end > content.length){
end = content.length; end = content.length;
} }
var match_content = content.substr(start, end); var matchContent = content.substring(start, end);
// highlight all keywords debugger
// 高亮关键字
keywords.forEach(function(keyword){ keywords.forEach(function(keyword){
var keywordReg = new RegExp(keyword, "gi"); var keywordReg = new RegExp(keyword, "gi");
match_content = match_content.replace(keywordReg, "<strong class=\"search-keyword\">"+keyword+"</strong>"); matchContent = matchContent.replace(keywordReg, "<strong class=\"search-keyword\">"+keyword+"</strong>");
}) })
searchResult += "<p class=\"search-result\">" + match_content +"...</p>"; resultItem.matchContent = matchContent
} }
searchResult += "</li>"; _this.searchResult.push(resultItem)
} }
}) })
searchResult += "</ul>";
this.searchResult = searchResult
console.log(searchResult)
} }
} }
}) })