站内搜索优化,归档
This commit is contained in:
parent
ee2b5a2da4
commit
9fde270ea6
@ -91,5 +91,5 @@ search:
|
|||||||
## Docs: https://hexo.io/docs/deployment.html
|
## Docs: https://hexo.io/docs/deployment.html
|
||||||
deploy:
|
deploy:
|
||||||
type: git
|
type: git
|
||||||
repo: git@github.com:sookie2010/sookie2010.github.io.git
|
repo: https://github.com/sookie2010/sookie2010.github.io.git
|
||||||
branch: master
|
branch: master
|
||||||
|
|||||||
@ -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
|
|
||||||
---
|
|
||||||
@ -13,17 +13,13 @@ menu:
|
|||||||
link: /
|
link: /
|
||||||
icon: icon-home
|
icon: icon-home
|
||||||
lab:
|
lab:
|
||||||
name: 实验室
|
name: 归档
|
||||||
link: /lab/
|
link: /archives/
|
||||||
icon: icon-lab
|
icon: icon-drawer
|
||||||
about:
|
about:
|
||||||
name: 关于
|
name: 关于
|
||||||
link: /about/
|
link: /about/
|
||||||
icon: icon-user-tie
|
icon: icon-user-tie
|
||||||
# comment:
|
|
||||||
# name: 留言
|
|
||||||
# link: /comment/
|
|
||||||
# icon: icon-bubbles2
|
|
||||||
rss:
|
rss:
|
||||||
name: RSS
|
name: RSS
|
||||||
link: /atom.xml
|
link: /atom.xml
|
||||||
|
|||||||
@ -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>
|
|
||||||
<% } %>
|
|
||||||
@ -23,7 +23,7 @@ if(pagination) {
|
|||||||
|
|
||||||
let currentPosts = [];
|
let currentPosts = [];
|
||||||
site.posts.each(function(post) {
|
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)
|
currentPosts.push(post)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -41,9 +41,8 @@ if(pagination) {
|
|||||||
%>
|
%>
|
||||||
<li class="archive-item">
|
<li class="archive-item">
|
||||||
<a href="<%=url_for(post.permalink) %>">
|
<a href="<%=url_for(post.permalink) %>">
|
||||||
<div class="archive-div">
|
<span class="title"><%=post.title %></span>
|
||||||
<%=post.title %>
|
<span class="date">---- <%=date(post.date, 'YYYY-MM-DD HH:mm') %></span>
|
||||||
</div>
|
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<%
|
<%
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
</header>
|
</header>
|
||||||
<p class="post-meta text-center">
|
<p class="post-meta text-center">
|
||||||
<%- post.author || '柠烟夏季' %> 发表于
|
<%- post.author || '柠烟夏季' %> 发表于
|
||||||
<%- partial('post/date', { date_format: 'YYYY-MM-DD' }) %>
|
<%- partial('post/date', { date_format: 'YYYY-MM-DD HH:mm' }) %>
|
||||||
</p>
|
</p>
|
||||||
<div class="post-content">
|
<div class="post-content">
|
||||||
<%- post.content %>
|
<%- post.content %>
|
||||||
|
|||||||
@ -1,71 +1,65 @@
|
|||||||
<header class="header">
|
<header class="header">
|
||||||
<section class="container header-main">
|
<section class="container header-main">
|
||||||
<div class="logo">
|
<div class="logo">
|
||||||
<a href="<%- url_for() %>">
|
<a href="<%- url_for() %>">
|
||||||
<div class="cover">
|
<div class="cover">
|
||||||
<div class="name"><%= config.title %></div>
|
<div class="name"><%= config.title %></div>
|
||||||
<div class="description"><%= config.subtitle %></div>
|
<div class="description"><%= config.subtitle %></div>
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="dropnav icon-paragraph-justify" id="JELON__btnDropNav"></div>
|
</a>
|
||||||
<!-- 导航栏 -->
|
</div>
|
||||||
<ul class="menu hidden" id="JELON__menu">
|
<div class="dropnav icon-paragraph-justify" id="JELON__btnDropNav"></div>
|
||||||
<% 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' : '' %>">
|
<ul class="menu hidden" id="JELON__menu">
|
||||||
<a href="<%= url_for(theme.menu[i].link) %>" title="<%= theme.menu[i].name %>" class="<%= theme.menu[i].icon %>"> <%= theme.menu[i].name %></a>
|
<% for (var i in theme.menu) { %>
|
||||||
</li>
|
<li rel="<%= url_for(path) %>" class="item <%= url_for(theme.menu[i].link) == url_for(path).substring(0, url_for(path).lastIndexOf('/') + 1) ? 'current' : '' %>">
|
||||||
<% } %>
|
<a href="<%= url_for(theme.menu[i].link) %>" title="<%= theme.menu[i].name %>" class="<%= theme.menu[i].icon %>"> <%= theme.menu[i].name %></a>
|
||||||
|
</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" @focus="searchInit" placeholder="站内搜索"/></div>
|
||||||
|
<!-- 搜索结果区 -->
|
||||||
|
<div id="search-result-box" >
|
||||||
|
<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>
|
</ul>
|
||||||
<!-- 搜索框 -->
|
<!-- 搜索未初始化完毕时显示 -->
|
||||||
<div id="search-box">
|
<div style="text-align:center;padding:10px 0" v-else-if="searchIniting">
|
||||||
<div class="icon"><span class="icon-search"></span></div>
|
<img src="<%= config.root%>img/loading-bar.gif" style="height:8px;width:auto"/>
|
||||||
<div class="input-box"><input type="text" id="search-input" v-model="queryText" placeholder="站内搜索"/></div>
|
|
||||||
<!-- 搜索结果区 -->
|
|
||||||
<div id="search-result-box" >
|
|
||||||
<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>
|
||||||
<div class="profile clearfix">
|
<!-- 无匹配时显示 -->
|
||||||
<div class="feeds fl">
|
<p class="search-result" v-else>没有搜索到任何结果</p>
|
||||||
<% if (theme.head_links.enable) { %>
|
</div>
|
||||||
<%
|
</div>
|
||||||
var supList = theme.head_links.list.sup,
|
<div class="profile clearfix">
|
||||||
subList = theme.head_links.list.sub;
|
<div class="feeds fl">
|
||||||
%>
|
<% if (theme.head_links.enable) { %>
|
||||||
<p class="links">
|
<%
|
||||||
<% for (var i in supList) { %>
|
var supList = theme.head_links.list.sup,
|
||||||
<a href="<%= supList[i]['link'] %>" target="_blank"><%= supList[i]['name'] %></a>
|
subList = theme.head_links.list.sub;
|
||||||
<% if (i != 'last') { %>|<% } %>
|
%>
|
||||||
<% } %>
|
<p class="links">
|
||||||
</p>
|
<% for (var i in supList) { %>
|
||||||
<p class="sns">
|
<a href="<%= supList[i]['link'] %>" target="_blank"><%= supList[i]['name'] %></a>
|
||||||
<% for (var j in subList) { %>
|
<% if (i != 'last') { %>|<% } %>
|
||||||
<a href="<%= subList[j]['link'] %>" class="<%= j %>" target="_blank"><b>■</b> <%= subList[j]['name'] %></a>
|
<% } %>
|
||||||
<% } %>
|
</p>
|
||||||
<!--
|
<p class="sns">
|
||||||
<a href="javascript: void(0);" class="wechat">
|
<% for (var j in subList) { %>
|
||||||
<b>■</b>
|
<a href="<%= subList[j]['link'] %>" class="<%= j %>" target="_blank"><b>■</b> <%= subList[j]['name'] %></a>
|
||||||
公众号
|
<% } %>
|
||||||
<span class="popover">
|
</p>
|
||||||
<img src="<%= url_for('img/wechat_mp.jpg') %>" width="120" height="120" alt="我的微信订阅号">
|
<% } %>
|
||||||
<i class="arrow"></i>
|
</div>
|
||||||
</span>
|
<div class="avatar fr">
|
||||||
</a>
|
<img src="<%- theme.avatar %>" alt="avatar" title="Sookie">
|
||||||
-->
|
</div>
|
||||||
</p>
|
</div>
|
||||||
<% } %>
|
</section>
|
||||||
</div>
|
|
||||||
<div class="avatar fr">
|
|
||||||
<img src="<%- theme.avatar %>" alt="avatar" title="Sookie">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</header>
|
</header>
|
||||||
|
|||||||
@ -120,17 +120,10 @@
|
|||||||
|
|
||||||
.archive-wapper
|
.archive-wapper
|
||||||
list-style none
|
list-style none
|
||||||
display flex
|
.archive-item > a
|
||||||
flex-wrap wrap
|
display block
|
||||||
justify-content space-between
|
font-size 16px
|
||||||
.archive-item
|
line-height 30px
|
||||||
display inline-block
|
.date
|
||||||
height 50px
|
color #999
|
||||||
padding 5px
|
font-size 14px
|
||||||
width 30%
|
|
||||||
> a > .archive-div
|
|
||||||
border 1px solid #a7a7a7
|
|
||||||
border-radius 5px
|
|
||||||
height 100%
|
|
||||||
padding 5px
|
|
||||||
box-sizing border-box
|
|
||||||
|
|||||||
BIN
themes/hexo-theme-xups/source/img/loading-bar.gif
Normal file
BIN
themes/hexo-theme-xups/source/img/loading-bar.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
@ -1,95 +1,117 @@
|
|||||||
(function(){
|
(function(){
|
||||||
var articleDatas = null;
|
var articleDatas = null,
|
||||||
var resultDiv = null;
|
resultDiv = null,
|
||||||
|
initCallback = function(){};
|
||||||
|
function executeSearch(keywords) {
|
||||||
|
var _this = this;
|
||||||
|
articleDatas.forEach(function(article){
|
||||||
|
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 = article.content ? article.content.indexOf(keyword) : -1;
|
||||||
|
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) {
|
||||||
|
var resultItem = {};
|
||||||
|
resultItem.url = article.url;
|
||||||
|
resultItem.title = article.title;
|
||||||
|
if (first_occur >= 0) {
|
||||||
|
// 截取出关键字所在的前后若干字符
|
||||||
|
var start = first_occur - 10;
|
||||||
|
var end = first_occur + 15;
|
||||||
|
if(start <= 0){
|
||||||
|
start = 0;
|
||||||
|
end = 25;
|
||||||
|
}
|
||||||
|
if(end > article.content.length){
|
||||||
|
end = article.content.length;
|
||||||
|
}
|
||||||
|
var matchContent = article.content.substring(start, end);
|
||||||
|
// 高亮关键字
|
||||||
|
keywords.forEach(function(keyword){
|
||||||
|
var keywordReg = new RegExp(keyword, "gi");
|
||||||
|
matchContent = matchContent.replace(keywordReg, "<strong class=\"search-keyword\">"+keyword+"</strong>");
|
||||||
|
})
|
||||||
|
resultItem.matchContent = matchContent
|
||||||
|
}
|
||||||
|
_this.searchResult.push(resultItem)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
new Vue({
|
new Vue({
|
||||||
el: "#search-box",
|
el: "#search-box",
|
||||||
data: {
|
data: {
|
||||||
queryText: null,
|
queryText: null,
|
||||||
searchResult: []
|
searchResult: [],
|
||||||
|
searchIniting: false // 搜索是否正在初始化(search.xml文件很大, 异步ajax以及xml解析需要时间)
|
||||||
},
|
},
|
||||||
mounted: function() {
|
mounted: function() {
|
||||||
resultDiv = document.getElementById("search-result-box")
|
resultDiv = document.getElementById("search-result-box");
|
||||||
axios({
|
},
|
||||||
url: "/search.xml"
|
methods : {
|
||||||
}).then(function(response){
|
searchInit: function() {
|
||||||
var xmlDoms = null
|
if(articleDatas || this.searchIniting) return;
|
||||||
if(window.DOMParser) {
|
this.searchIniting = true;
|
||||||
var parser = new DOMParser()
|
var _this = this;
|
||||||
xmlDoms = parser.parseFromString(response.data, "application/xml")
|
axios({
|
||||||
} else {
|
url: "/search.xml"
|
||||||
xmlDoms = new ActiveXObject("Microsoft.XMLDOM");
|
}).then(function(response){
|
||||||
xmlDoms.async = false;
|
var xmlDoms = null
|
||||||
xmlDoms.loadXML(response.data);
|
if(window.DOMParser) {
|
||||||
}
|
var parser = new DOMParser()
|
||||||
//找出所有文章的标题 正文 URL
|
xmlDoms = parser.parseFromString(response.data, "application/xml")
|
||||||
articleDatas = Array.prototype.map.call(xmlDoms.getElementsByTagName("entry"), function(item){
|
} else {
|
||||||
return {
|
xmlDoms = new ActiveXObject("Microsoft.XMLDOM");
|
||||||
title: item.getElementsByTagName("title")[0].textContent,
|
xmlDoms.async = false;
|
||||||
content: item.getElementsByTagName("content")[0].textContent,
|
xmlDoms.loadXML(response.data);
|
||||||
url: item.getElementsByTagName("url")[0].textContent,
|
|
||||||
}
|
}
|
||||||
})
|
//找出所有文章的标题 正文 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: {
|
watch: {
|
||||||
queryText: function(newVal, oldVal) {
|
queryText: function(newVal, oldVal) {
|
||||||
this.searchResult.length = 0;
|
this.searchResult.length = 0;
|
||||||
if(!resultDiv) return;
|
if(!resultDiv) return;
|
||||||
if(newVal && newVal.trim() && articleDatas) {
|
if(newVal && newVal.trim()) {
|
||||||
resultDiv.style.display = "block"
|
resultDiv.style.display = "block";
|
||||||
} else {
|
} else {
|
||||||
resultDiv.style.display = "none"
|
resultDiv.style.display = "none";
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var keywords = newVal.trim().toLowerCase().split(/[\s\-]+/);
|
var keywords = newVal.trim().toLowerCase().split(/[\s\-]+/);
|
||||||
var _this = this;
|
var _this = this;
|
||||||
articleDatas.forEach(function(article){
|
if(this.searchIniting) {
|
||||||
var isMatch = true;
|
initCallback = function(){
|
||||||
var title = article.title.trim().toLowerCase();
|
executeSearch.call(this, keywords);
|
||||||
var content = article.content.trim().replace(/<[^>]+>/g,"").toLowerCase();
|
|
||||||
var index_title = -1;
|
|
||||||
var index_content = -1;
|
|
||||||
var first_occur = -1; //关键字在正文当中第一次出现的位置
|
|
||||||
keywords.forEach(function(keyword, i) {
|
|
||||||
index_title = title ? title.indexOf(keyword) : -1;
|
|
||||||
index_content = content ? content.indexOf(keyword) : -1;
|
|
||||||
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) {
|
|
||||||
var resultItem = {};
|
|
||||||
resultItem.url = article.url;
|
|
||||||
resultItem.title = article.title;
|
|
||||||
if (first_occur >= 0) {
|
|
||||||
// 截取出关键字所在的前后若干字符
|
|
||||||
var start = first_occur - 10;
|
|
||||||
var end = first_occur + 15;
|
|
||||||
if(start <= 0){
|
|
||||||
start = 0;
|
|
||||||
end = 25;
|
|
||||||
}
|
|
||||||
if(end > content.length){
|
|
||||||
end = content.length;
|
|
||||||
}
|
|
||||||
var matchContent = content.substring(start, end);
|
|
||||||
// 高亮关键字
|
|
||||||
keywords.forEach(function(keyword){
|
|
||||||
var keywordReg = new RegExp(keyword, "gi");
|
|
||||||
matchContent = matchContent.replace(keywordReg, "<strong class=\"search-keyword\">"+keyword+"</strong>");
|
|
||||||
})
|
|
||||||
resultItem.matchContent = matchContent
|
|
||||||
}
|
|
||||||
_this.searchResult.push(resultItem)
|
|
||||||
}
|
}
|
||||||
})
|
} else {
|
||||||
|
executeSearch.call(this, keywords);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user