全文搜索

This commit is contained in:
结发受长生 2018-05-08 17:37:31 +08:00
parent 4f7c64f6bc
commit 04442faf3d
13 changed files with 12844 additions and 36 deletions

View File

@ -7,7 +7,7 @@ server:
header: true
# Site
title: 日月追影俯河山
title: Silence
subtitle: 世上有条唯一的路,除了你无人能走
description:
keywords:
@ -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

@ -20,10 +20,10 @@ menu:
name: 关于
link: /about/
icon: icon-user-tie
comment:
name: 留言
link: /comment/
icon: icon-bubbles2
# comment:
# name: 留言
# link: /comment/
# icon: icon-bubbles2
rss:
name: RSS
link: /atom.xml

View File

@ -1,2 +1,5 @@
<!-- 这里放网站js脚本 -->
<%- js('js/main') %>
<%- js('js/main') %>
<%- js('js/lib/vue.min') %>
<%- js('js/lib/axios.min') %>
<%- js('js/local_search') %>

View File

@ -3,12 +3,13 @@
<div class="logo">
<a href="<%- url_for() %>">
<div class="cover">
<span class="name"><%= config.title %></span>
<span class="description"><%= config.subtitle %></span>
<div class="name"><%= config.title %></div>
<div class="description"><%= config.subtitle %></div>
</div>
</a>
</div>
<div class="dropnav icon-paragraph-justify" id="JELON__btnDropNav"></div>
<!-- 导航栏 -->
<ul class="menu hidden" id="JELON__menu">
<% for (var i in theme.menu) { %>
<li rel="<%= url_for(path) %>" class="item <%= url_for(theme.menu[i].link) == url_for(path).substring(0, url_for(path).lastIndexOf('/') + 1) ? 'current' : '' %>">
@ -16,6 +17,17 @@
</li>
<% } %>
</ul>
<!-- 搜索框 -->
<div id="search-box">
<div class="icon"><span class="icon-search"></span></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 v-html="searchResult"></div>
<!-- 无匹配时显示 -->
<p class="no-result" v-if="!searchResult">没有搜索到任何结果</p>
</div>
</div>
<div class="profile clearfix">
<div class="feeds fl">
<% if (theme.head_links.enable) { %>

View File

@ -3,7 +3,7 @@
*/
.container
max-width 1180px
_width 1180px
min-width 1070px
background-color c-fff
margin 0 auto 10px
text-left()

View File

@ -9,10 +9,55 @@
.header-main
position relative
height 68px
margin-bottom 0
.header .logo
float left
width 260px
display flex
.logo
width 160px
.menu
margin 0
padding 10px
list-style-type none
#search-box
padding 10px
font-size 16px
flex-grow 1
line-height 48px
display flex
position relative
.input-box
box-sizing border-box
padding 0 3px
flex-grow 1
> #search-input
border none
border-bottom 1px solid #9e9e9e
background inherit
width 50%
transition width 0.3s ease-in
outline:none
&:focus
width 80%
> #search-result-box
position absolute
z-index 100
line-height 1.2
top 48px
width 300px
max-height 600px
overflow-y auto
background #eee
border 1px solid #333
border-radius 5px
word-break break-all
padding 7px
ul
list-style none
padding-left 0
margin-top 0
a.search-result-title
color #3272b5
font-size 20px
strong.search-keyword
color #ff776d
.logo
a
position relative
@ -32,24 +77,18 @@
width 100%
transition top .5s
.name
display block
height 100%
font-size 28px
font-family "HomizioNova", "Microsoft Yahei"
font-style italic
.description
display block
line-height (@height/2)
height 100%
color c-fff
background-color #51cc87
opacity .85
&:hover .cover
top -100%
.header .menu
margin 0
padding 10px
float left
list-style-type none
.menu
.item
float left
@ -63,11 +102,6 @@
color #ff5e52
.current a
color #ff5e52
.header .profile
position absolute
right 0
top 0
height 68px
.profile
.avatar
width 50px

View File

@ -1,9 +1,10 @@
/*!
*
*/
@media screen and (min-width: 1440px)
/*
@media screen and (max-width: 1440px)
.container
max-width 1340px
max-width 1140px
.content
min-height 500px
@media screen and (max-width: 1000px) and (min-width: 960px)
@ -11,10 +12,12 @@
max-width 952px
.content
min-height 500px
*/
@media screen and (max-width: 959px)
.container
margin-bottom 10px
padding 0 10px
min-width auto
.content
min-height 500px
.sidebar
@ -25,12 +28,13 @@
.header
.header-main
height auto
padding-bottom 10px
.logo
float none
width auto
width 100%
.profile
display none
#search-box
display none
.menu
float none
padding 8px 10px
@ -38,6 +42,9 @@
background-color #fff
border-top 0
overflow hidden
position absolute
right 10px
top 69px
.item
width 50%
height auto

View File

@ -1,8 +1,6 @@
if (!window['String']['prototype']['trim']) {
window['String']['prototype']['trim'] = function () {
return this.replace(/^\s+|\s+$/g, '');
};
}
window.String.prototype.trim = window.String.prototype.trim || function () {
return this.replace(/^\s+|\s+$/g, '');
};
var JELON = window.JELON || {};
;(function (JL) {
var constants = {

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,189 @@
// 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
},
mounted: function() {
axios({
url: "/search.xml"
}).then(function(response){
var xmlDoms = null
if(window.DOMParser) {
var parser = new DOMParser()
xmlDoms = parser.parseFromString(response.data, "application/xml")
} else {
var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = false;
xmlDoms = xmlDoc.loadXML(response.data);
}
//找出所有文章的标题 正文 URL
articleDatas = Array.prototype.map.call(xmlDoms.getElementsByTagName("entry"), function(item){
return {
title: item.getElementsByTagName("title")[0].innerHTML,
content: item.getElementsByTagName("content")[0].innerHTML,
url: item.getElementsByTagName("url")[0].innerHTML,
}
})
});
},
watch: {
queryText: function(newVal, oldVal) {
if(!newVal || !newVal.trim() || !articleDatas) return
var keywords = newVal.trim().toLowerCase().split(/[\s\-]+/);
var searchResult = '<ul class=\"search-result-list\">';
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 index_title = -1;
var index_content = -1;
var first_occur = -1;
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;
}
}
});
}
if (isMatch) {
searchResult += "<li><a href='"+ data_url +
"' class='search-result-title' target='_blank'>"+ "> " +data_title+"</a>";
var content = article.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 keywordReg = new RegExp(keyword, "gi");
match_content = match_content.replace(keywordReg, "<strong class=\"search-keyword\">"+keyword+"</strong>");
})
searchResult += "<p class=\"search-result\">" + match_content +"...</p>";
}
searchResult += "</li>";
}
})
searchResult += "</ul>";
this.searchResult = searchResult
console.log(searchResult)
}
}
})
})()