站内搜索功能完成

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
## 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: http://localhost:6603
url: https://www.colorfulsweet.site
# url: http://localhost:6603
root: /
permalink: :title/
permalink_defaults:

View File

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

View File

@ -55,7 +55,10 @@
margin-top 0
a.search-result-title
color #3272b5
font-size 20px
font-size 18px
p.search-result
font-size 14px
margin 0.6em 0
strong.search-keyword
color #ff776d
.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(){
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;
new Vue({
el: "#search-box",
data: {
queryText: null,
searchResult: null
searchResult: []
},
mounted: function() {
axios({
@ -124,22 +31,21 @@ new Vue({
},
watch: {
queryText: function(newVal, oldVal) {
this.searchResult.length = 0;
if(!newVal || !newVal.trim() || !articleDatas) return
var keywords = newVal.trim().toLowerCase().split(/[\s\-]+/);
var searchResult = '<ul class=\"search-result-list\">';
var _this = this;
articleDatas.forEach(function(article){
var isMatch = true;
var content_index = [];
var data_title = article.title.trim().toLowerCase();
var data_content = article.content.trim().replace(/<[^>]+>/g,"").toLowerCase();
var data_url = article.url;
var title = article.title.trim().toLowerCase();
var content = article.content.trim().replace(/<[^>]+>/g,"").toLowerCase();
var index_title = -1;
var index_content = -1;
var first_occur = -1;
if(data_title && data_content) {
var first_occur = -1; //关键字在正文当中第一次出现的位置
if(title && content) {
keywords.forEach(function(keyword, i) {
index_title = data_title.indexOf(keyword);
index_content = data_content.indexOf(keyword);
index_title = title.indexOf(keyword);
index_content = content.indexOf(keyword);
if( index_title < 0 && index_content < 0 ){
isMatch = false;
} else {
@ -153,13 +59,13 @@ new Vue({
});
}
if (isMatch) {
searchResult += "<li><a href='"+ data_url +
"' class='search-result-title' target='_blank'>"+ "> " +data_title+"</a>";
var content = article.content.trim().replace(/<[^>]+>/g,"");
var resultItem = {};
resultItem.url = article.url;
resultItem.title = article.title;
if (first_occur >= 0) {
// cut out characters
var start = first_occur - 6;
var end = first_occur + 6;
var end = first_occur + 15;
if(start < 0){
start = 0;
}
@ -169,20 +75,18 @@ new Vue({
if(end > content.length){
end = content.length;
}
var match_content = content.substr(start, end);
// highlight all keywords
var matchContent = content.substring(start, end);
debugger
// 高亮关键字
keywords.forEach(function(keyword){
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)
}
}
})