站内搜索优化,归档

This commit is contained in:
结发受长生 2018-05-21 15:24:55 +08:00
parent ee2b5a2da4
commit 9fde270ea6
10 changed files with 170 additions and 221 deletions

View File

@ -91,5 +91,5 @@ search:
## Docs: https://hexo.io/docs/deployment.html
deploy:
type: git
repo: git@github.com:sookie2010/sookie2010.github.io.git
repo: https://github.com/sookie2010/sookie2010.github.io.git
branch: master

View File

@ -1,28 +0,0 @@
---
title: 实验室
date: 2016-02-01 20:29:57
pageid: lab
projects:
blog_demo:
title: Blog Demo
time: 2016-10-10
content:
1:
name: 基于 vue + vuex + bootstrap 的 blog demo
link: https://github.com/jangdelong/vue-blog-demo
hexo_theme_xups:
title: hexo-theme-xups 博客主题
time: 2016-03-12
content:
1:
name: 基于 hexo 静态博客系统的 博客主题 xups
link: https://github.com/jangdelong/hexo-theme-xups
typecho_theme_xups:
title: Typecho 博客主题
time: 2015-10-15
content:
1:
name: 基于 php 博客系统 typecho 的主题 xups
link: https://github.com/jangdelong/typecho-theme-xups
---

View File

@ -13,17 +13,13 @@ menu:
link: /
icon: icon-home
lab:
name: 实验室
link: /lab/
icon: icon-lab
name: 归档
link: /archives/
icon: icon-drawer
about:
name: 关于
link: /about/
icon: icon-user-tie
# comment:
# name: 留言
# link: /comment/
# icon: icon-bubbles2
rss:
name: RSS
link: /atom.xml

View File

@ -1,27 +0,0 @@
<!-- 自定义实验室页 -->
<section>
<img title="图片摄于2017年1月1日深圳梧桐山 By iPhone 7。" src="<%- url_for('/img/lab/banner.jpg?v=3') %>" alt="Lab Banner" style="max-width: 100%;" alt="Banner" >
</section>
<%
var projects = page.projects;
for (var i in projects) {
%>
<p style="color: #444;">
<!--
<span class="icon-cogs"></span>
-->
<span class="icon-price-tags"></span>
<%- date(projects[i].time, 'YYYY-MM-DD') %> <%- projects[i].title %>
</p>
<ul style="list-style-type: none;">
<% var content = projects[i].content; %>
<% for (var j in content) { %>
<li>
<a href="<%- content[j].link %>" target="_blank" class="icon-lab fr" title="查看代码" style="color: #ff5e52; border-bottom: none; font-size: 16px; margin-top: 2.5px;"></a>
<span><%- content[j].name %></span>
</li>
<% } %>
</ul>
<% } %>

View File

@ -23,7 +23,7 @@ if(pagination) {
let currentPosts = [];
site.posts.each(function(post) {
if(post.date.year() == page.year && (post.date.month()+1 == page.month || !page.month)) {
if((post.date.year() == page.year || !page.year) && (post.date.month()+1 == page.month || !page.month)) {
currentPosts.push(post)
}
})
@ -41,9 +41,8 @@ if(pagination) {
%>
<li class="archive-item">
<a href="<%=url_for(post.permalink) %>">
<div class="archive-div">
<%=post.title %>
</div>
<span class="title"><%=post.title %></span>
<span class="date">---- <%=date(post.date, 'YYYY-MM-DD HH:mm') %></span>
</a>
</li>
<%

View File

@ -5,7 +5,7 @@
</header>
<p class="post-meta text-center">
<%- post.author || '柠烟夏季' %> 发表于
<%- partial('post/date', { date_format: 'YYYY-MM-DD' }) %>
<%- partial('post/date', { date_format: 'YYYY-MM-DD HH:mm' }) %>
</p>
<div class="post-content">
<%- post.content %>

View File

@ -20,15 +20,19 @@
<!-- 搜索框 -->
<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 class="input-box"><input type="text" id="search-input" v-model="queryText" @focus="searchInit" placeholder="站内搜索"/></div>
<!-- 搜索结果区 -->
<div id="search-result-box" >
<ul class="search-result-list" v-if="searchResult.length">
<ul class="search-result-list" v-if="searchResult.length && !searchIniting">
<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>
<!-- 搜索未初始化完毕时显示 -->
<div style="text-align:center;padding:10px 0" v-else-if="searchIniting">
<img src="<%= config.root%>img/loading-bar.gif" style="height:8px;width:auto"/>
</div>
<!-- 无匹配时显示 -->
<p class="search-result" v-else>没有搜索到任何结果</p>
</div>
@ -50,16 +54,6 @@
<% for (var j in subList) { %>
<a href="<%= subList[j]['link'] %>" class="<%= j %>" target="_blank"><b>■</b> <%= subList[j]['name'] %></a>
<% } %>
<!--
<a href="javascript: void(0);" class="wechat">
<b>■</b>
公众号
<span class="popover">
<img src="<%= url_for('img/wechat_mp.jpg') %>" width="120" height="120" alt="我的微信订阅号">
<i class="arrow"></i>
</span>
</a>
-->
</p>
<% } %>
</div>

View File

@ -120,17 +120,10 @@
.archive-wapper
list-style none
display flex
flex-wrap wrap
justify-content space-between
.archive-item
display inline-block
height 50px
padding 5px
width 30%
> a > .archive-div
border 1px solid #a7a7a7
border-radius 5px
height 100%
padding 5px
box-sizing border-box
.archive-item > a
display block
font-size 16px
line-height 30px
.date
color #999
font-size 14px

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -1,58 +1,17 @@
(function(){
var articleDatas = null;
var resultDiv = null;
new Vue({
el: "#search-box",
data: {
queryText: null,
searchResult: []
},
mounted: function() {
resultDiv = document.getElementById("search-result-box")
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 {
xmlDoms = new ActiveXObject("Microsoft.XMLDOM");
xmlDoms.async = false;
xmlDoms.loadXML(response.data);
}
//找出所有文章的标题 正文 URL
articleDatas = Array.prototype.map.call(xmlDoms.getElementsByTagName("entry"), function(item){
return {
title: item.getElementsByTagName("title")[0].textContent,
content: item.getElementsByTagName("content")[0].textContent,
url: item.getElementsByTagName("url")[0].textContent,
}
})
});
},
watch: {
queryText: function(newVal, oldVal) {
this.searchResult.length = 0;
if(!resultDiv) return;
if(newVal && newVal.trim() && articleDatas) {
resultDiv.style.display = "block"
} else {
resultDiv.style.display = "none"
return
}
var keywords = newVal.trim().toLowerCase().split(/[\s\-]+/);
var articleDatas = null,
resultDiv = null,
initCallback = function(){};
function executeSearch(keywords) {
var _this = this;
articleDatas.forEach(function(article){
var isMatch = true;
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; //关键字在正文当中第一次出现的位置
var isMatch = true,
title = article.title.trim().toLowerCase(),
index_title = -1, index_content = -1,
first_occur = -1; //关键字在正文当中第一次出现的位置
keywords.forEach(function(keyword, i) {
index_title = title ? title.indexOf(keyword) : -1;
index_content = content ? content.indexOf(keyword) : -1;
index_content = article.content ? article.content.indexOf(keyword) : -1;
if( index_title < 0 && index_content < 0 ){
isMatch = false;
} else {
@ -76,10 +35,10 @@ new Vue({
start = 0;
end = 25;
}
if(end > content.length){
end = content.length;
if(end > article.content.length){
end = article.content.length;
}
var matchContent = content.substring(start, end);
var matchContent = article.content.substring(start, end);
// 高亮关键字
keywords.forEach(function(keyword){
var keywordReg = new RegExp(keyword, "gi");
@ -89,7 +48,70 @@ new Vue({
}
_this.searchResult.push(resultItem)
}
})
});
}
new Vue({
el: "#search-box",
data: {
queryText: null,
searchResult: [],
searchIniting: false // 搜索是否正在初始化(search.xml文件很大, 异步ajax以及xml解析需要时间)
},
mounted: function() {
resultDiv = document.getElementById("search-result-box");
},
methods : {
searchInit: function() {
if(articleDatas || this.searchIniting) return;
this.searchIniting = true;
var _this = this;
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 {
xmlDoms = new ActiveXObject("Microsoft.XMLDOM");
xmlDoms.async = false;
xmlDoms.loadXML(response.data);
}
//找出所有文章的标题 正文 URL
articleDatas = Array.prototype.map.call(xmlDoms.getElementsByTagName("entry"), function(item){
return {
title: item.getElementsByTagName("title")[0].textContent,
content: item.getElementsByTagName("content")[0].textContent.trim().replace(/<[^>]+>/g,"").toLowerCase(),
url: item.getElementsByTagName("url")[0].textContent,
}
});
_this.searchIniting = false;
initCallback.call(_this);
}).catch(function(){
_this.searchIniting = false;
_this.searchInit();
});
}
},
watch: {
queryText: function(newVal, oldVal) {
this.searchResult.length = 0;
if(!resultDiv) return;
if(newVal && newVal.trim()) {
resultDiv.style.display = "block";
} else {
resultDiv.style.display = "none";
return
}
var keywords = newVal.trim().toLowerCase().split(/[\s\-]+/);
var _this = this;
if(this.searchIniting) {
initCallback = function(){
executeSearch.call(this, keywords);
}
} else {
executeSearch.call(this, keywords);
}
}
}
})