Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
大白技术控
yanglr2010
提交
b6918d8c
Y
yanglr2010
项目概览
大白技术控
/
yanglr2010
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Y
yanglr2010
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
b6918d8c
编写于
8月 07, 2019
作者:
EvanOne(文一)
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
refactor: Optimize local search
chore: Change i18n
上级
852f2494
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
52 addition
and
83 deletion
+52
-83
languages/en.yml
languages/en.yml
+1
-1
languages/zh-CN.yml
languages/zh-CN.yml
+1
-1
layout/_third-party/search/localsearch.pug
layout/_third-party/search/localsearch.pug
+50
-81
未找到文件。
languages/en.yml
浏览文件 @
b6918d8c
...
...
@@ -73,7 +73,7 @@ algolia_search:
# Local search
local_search
:
input_placeholder
:
S
tart to search
input_placeholder
:
S
earch for Posts
hits_empty
:
We didn't find any results for the search
# Reward
...
...
languages/zh-CN.yml
浏览文件 @
b6918d8c
...
...
@@ -73,7 +73,7 @@ algolia_search:
# 本地搜索
local_search
:
input_placeholder
:
开始搜索
input_placeholder
:
搜索文章
hits_empty
:
没有找到任何搜索结果
# 打赏
...
...
layout/_third-party/search/localsearch.pug
浏览文件 @
b6918d8c
...
...
@@ -55,26 +55,27 @@ if theme.local_search.enable
return {
title: $('title', this).text(),
content: $('content', this).text(),
url: $('url', this).text(),
categories: $('category', this).text().trim().split(/[\s]+/),
tags: $('tag', this).text().trim().split(/[\s]+/)
url: $('url', this).text()
};
}).get() : res;
var $input = $('.localsearch-input-wrapper input');
var $result = $('.localsearch-result');
// 搜索对象(标题
,标签,分类,内容)的权值
,影响显示顺序
var WEIGHT = { title: 100,
tag: 10, category: 10,
content: 1 };
// 搜索对象(标题
、内容)的权重
,影响显示顺序
var WEIGHT = { title: 100, content: 1 };
var searchPost = function () {
var searchText = $input.val().toLowerCase().trim();
// 根据空白字符分隔关键字
var keywords = searchText.split(/[\s]+/);
// 将关键字进行排列组合,使得搜索到结果的可能性更大
var groupKeywords = sortGroup(keywords);
// 搜索结果
var matchPosts = [];
// 有多个关键字时,将原文字整个保存下来
if (keywords.length > 1) {
keywords.push(searchText);
}
// 防止未输入字符时搜索
if (searchText.length > 0) {
...
...
@@ -82,34 +83,32 @@ if theme.local_search.enable
var isMatch = false;
// 没有标题的文章使用预设的 i18n 变量代替
var title = (data.title && data.title.trim()) || '!{_p("post.untitled")}';
;
var title = (data.title && data.title.trim()) || '!{_p("post.untitled")}';
var titleLower = title && title.toLowerCase();
// 删除 HTML 标签 和 所有空白字符
var content = data.content && data.content.replace(/<[^>]+>|\s+/, '');
var contentLower = content && content.toLowerCase();
// 删除重复的 /
var postURL = data.url && decodeURI(data.url).replace(/\/{2,}/, '/');
var tags = data.tags;
var categories = data.categories;
// 标题中匹配到的关键词
var titleHitSlice = [];
// 内容中匹配到的关键词
var contentHitSlice = [];
groupK
eywords.forEach(function (keyword) {
k
eywords.forEach(function (keyword) {
/**
* 获取匹配
文字
的索引
* 获取匹配
的关键词
的索引
* @param {String} keyword 要匹配的关键字
* @param {String} text 原文字
* @param {Boolean} caseSensitive 是否区分大小写
* @param {Number} weight
权重
* @param {Number} weight
匹配对象的权重。权重大的优先显示
* @return {Array}
*/
function getIndexByword (word, text, caseSensitive, weight) {
if (!word || !text) return [];
var startIndex = 0; //
开始匹配的
索引
var startIndex = 0; //
每次匹配的开始
索引
var index = -1; // 匹配到的索引值
var result = []; // 匹配结果
...
...
@@ -119,15 +118,27 @@ if theme.local_search.enable
}
while((index = text.indexOf(word, startIndex)) !== -1) {
result.push({ index: index, word: word, weight: weight });
var hasMatch = false;
// 索引位置相同的关键词,保留长度较长的
titleHitSlice.forEach(function (hit) {
if (hit.index === index &&
hit.word.length < word.length) {
hit.word = word;
hasMatch = true;
}
});
startIndex = index + word.length;
!hasMatch && result.push({ index: index, word: word, weight: weight });
}
return result;
}
titleHitSlice = titleHitSlice.concat(getIndexByword(keyword, titleLower, false, WEIGHT.title));
contentHitSlice = contentHitSlice.concat(getIndexByword(keyword, contentLower, false, WEIGHT.content));
titleHitSlice = titleHitSlice.concat(
getIndexByword(keyword, titleLower, false, WEIGHT.title));
contentHitSlice = contentHitSlice.concat(
getIndexByword(keyword, contentLower, false, WEIGHT.content));
});
var hitTitle = titleHitSlice.length;
...
...
@@ -138,20 +149,29 @@ if theme.local_search.enable
}
if (isMatch) {
;[titleHitSlice, contentHitSlice].forEach(function (hit) {
// 按照匹配文字的索引的递增顺序排序
hit.sort(function (left, right) {
return left.index - right.index;
});
});
/**
* 给
匹配的文本添加标记标签
* 给
文本中匹配到的关键词添加标记,从而进行高亮显示
* @param {String} text 原文本
* @param {Array} hitSlice 匹配项的索引信息
* @param {Number} start 开始索引
* @param {Number} end 结束索引
* @return {String}
*/
function highlightKeyword (text, hitSlice) {
function highlightKeyword (text, hitSlice
, start, end
) {
if (!text || !hitSlice || !hitSlice.length) return;
var startIndex = 0;
var result = '';
var startIndex = start;
var endIndex = end;
hitSlice.forEach(function (hit) {
// 匹配到较长的字符串后,防止再匹配较短的字符串
if (hit.index < startIndex) return;
var hitWordEnd = hit.index + hit.word.length;
...
...
@@ -160,16 +180,18 @@ if theme.local_search.enable
result += '<b>' + text.slice(hit.index, hitWordEnd) + '</b>';
startIndex = hitWordEnd;
});
result += text.slice(startIndex);
result += text.slice(startIndex
, endIndex
);
return result;
}
var postData = {};
//
计算
文章总的搜索权重
// 文章总的搜索权重
var postWeight = titleHitSlice.length * 100 + contentHitSlice.length;
var postTitle = highlightKeyword(title, titleHitSlice) || title;
var postContent = highlightKeyword(content, contentHitSlice) || content;
// 标记匹配关键词后的标题
var postTitle = highlightKeyword(title, titleHitSlice, 0, title.length) || title;
// 标记匹配关键词后的内容
var postContent;
// 截取匹配的第一个字符,前后共 200 个字符来显示
if (contentHitSlice.length > 0) {
...
...
@@ -177,9 +199,9 @@ if theme.local_search.enable
var start = firstIndex > 20 ? firstIndex - 20 : 0;
var end = firstIndex + 180;
postContent =
postContent.slice(
start, end);
postContent =
highlightKeyword(content, contentHitSlice,
start, end);
} else { // 未匹配到内容,直接截取前 200 个字符来显示
postContent =
postC
ontent.slice(0, 200);
postContent =
c
ontent.slice(0, 200);
}
postData.title = postTitle;
...
...
@@ -215,59 +237,6 @@ if theme.local_search.enable
searchPost();
}
});
/**
* 将关键字进行排列组合
* @param {Array} keywords 关键词数组
* @return {Array}
*/
function sortGroup (keywords) {
if (!Array.isArray(keywords)) return;
if (keywords.length <= 1) return keywords;
// 对数组中的元素进行组合
function groupSplit (arr, size) {
var r = []; // result
function group(t, a, n) { // tempArr, arr, num
if (n === 0) {
r[r.length] = t;
return;
}
for (var i = 0, l = a.length - n; i <= l; i++) {
var b = t.slice();
b.push(a[i]);
group(b, a.slice(i + 1), n - 1);
}
}
group([], arr, size);
return r;
}
// 组合结果
var result = [];
for (var i = keywords.length; i > 0; i--) {
var groupKeyword = groupSplit(keywords, i);
if (groupKeyword.length !== 0) {
groupKeyword.forEach(function (item) {
// 将排列组合后的项,连接成新的关键词
if (item.length > 1) {
result.push(item.join(''));
result.push(item.join(' '));
result.push(item.slice(0).reverse().join(''));
result.push(item.slice(0).reverse().join(' '));
} else {
result.push(item.join(''));
}
});
}
}
return result;
}
}
});
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录