Skip to content

Commit

Permalink
⚡ 优化搜索框代码
Browse files Browse the repository at this point in the history
  • Loading branch information
zkqiang committed May 23, 2021
1 parent 6b2ac16 commit 4a0cc42
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 139 deletions.
14 changes: 0 additions & 14 deletions layout/_partial/plugins/local-search.ejs

This file was deleted.

5 changes: 4 additions & 1 deletion layout/_partial/scripts.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@
<%- js_ex(theme.static_prefix.clipboard, 'clipboard.min.js', 'defer') %>
<% } %>

<% if(theme.search.enable){ %>
<%- js_ex(theme.static_prefix.internal_js, 'local-search.js') %>
<% } %>

<% if ((theme.footer.statistics.enable && theme.footer.statistics.source === 'busuanzi')
|| (page.meta !== false && theme.post.meta.views.enable && theme.post.meta.views.source === 'busuanzi')) { %>
<%- js_ex(theme.static_prefix.busuanzi, 'busuanzi.pure.mini.js', 'defer') %>
Expand All @@ -57,7 +61,6 @@
<% } %>

<%- partial('_partial/plugins/typed.ejs') %>
<%- partial('_partial/plugins/local-search.ejs') %>
<%- partial('_partial/plugins/math.ejs') %>
<%- partial('_partial/plugins/mermaid.ejs') %>
<%- partial('_partial/plugins/analytics.ejs') %>
Expand Down
3 changes: 2 additions & 1 deletion scripts/helpers/export-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ hexo.extend.helper.register('export_config', function() {
image_zoom : theme.post.image_zoom,
toc : theme.post.toc,
lazyload : theme.lazyload,
web_analytics: theme.web_analytics
web_analytics: theme.web_analytics,
search_path : theme.search.path
};
return `<script id="fluid-configs">
var Fluid = window.Fluid || {};
Expand Down
266 changes: 143 additions & 123 deletions source/js/local-search.js
Original file line number Diff line number Diff line change
@@ -1,140 +1,160 @@
// A local search script with the help of [hexo-generator-search](https://github.com/PaicHyperionDev/hexo-generator-search)
// Copyright (C) 2017
// Liam Huang <https://github.com/Liam0205>
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
// 02110-1301 USA
//
// Updated by Rook1e <https://github.com/0x2E>

// eslint-disable-next-line no-unused-vars
var searchFunc = function(path, search_id, content_id) {
// 0x00. environment initialization
'use strict';
var $input = document.getElementById(search_id);
var $resultContent = document.getElementById(content_id);

if ($resultContent.innerHTML.indexOf('list-group-item') === -1) {
$resultContent.innerHTML = '<div class="m-auto text-center"><div class="spinner-border" role="status"><span class="sr-only">Loading...</span></div><br/>Loading...</div>';
}
/* global CONFIG */

$.ajax({
// 0x01. load xml file
url : path,
dataType: 'xml',
success : function(xmlResponse) {
// 0x02. parse xml file
var dataList = jQuery('entry', xmlResponse).map(function() {
return {
title : jQuery('title', this).text(),
content: jQuery('content', this).text(),
url : jQuery('url', this).text()
};
}).get();

if ($resultContent.innerHTML.indexOf('list-group-item') === -1) {
$resultContent.innerHTML = '';
}
(function() {
// Modify by [hexo-generator-search](https://github.com/wzpan/hexo-generator-search)
function localSearchFunc(path, searchSelector, resultSelector) {
'use strict';
// 0x00. environment initialization
var $input = jQuery(searchSelector);
var $result = jQuery(resultSelector);

if ($input.length === 0) {
// eslint-disable-next-line no-console
throw Error('No element selected by the searchSelector');
}
if ($result.length === 0) {
// eslint-disable-next-line no-console
throw Error('No element selected by the resultSelector');
}

$input.addEventListener('input', function() {
// 0x03. parse query to keywords list
var str = '';
var keywords = this.value.trim().toLowerCase().split(/[\s-]+/);
$resultContent.innerHTML = '';
if (this.value.trim().length <= 0) {
return;
if ($result.attr('class').indexOf('list-group-item') === -1) {
$result.html('<div class="m-auto text-center"><div class="spinner-border" role="status"><span class="sr-only">Loading...</span></div><br/>Loading...</div>');
}

$.ajax({
// 0x01. load xml file
url : path,
dataType: 'xml',
success : function(xmlResponse) {
// 0x02. parse xml file
var dataList = jQuery('entry', xmlResponse).map(function() {
return {
title : jQuery('title', this).text(),
content: jQuery('content', this).text(),
url : jQuery('url', this).text()
};
}).get();

if ($result.html().indexOf('list-group-item') === -1) {
$result.html('');
}
// 0x04. perform local searching
dataList.forEach(function(data) {
var isMatch = true;
if (!data.title || data.title.trim() === '') {
data.title = 'Untitled';

$input.on('input', function() {
// 0x03. parse query to keywords list
var content = $input.val();
var resultHTML = '';
var keywords = content.trim().toLowerCase().split(/[\s-]+/);
$result.html('');
if (content.trim().length <= 0) {
return $input.removeClass('invalid').removeClass('valid');
}
var orig_data_title = data.title.trim();
var data_title = orig_data_title.toLowerCase();
var orig_data_content = data.content.trim().replace(/<[^>]+>/g, '');
var data_content = orig_data_content.toLowerCase();
var data_url = data.url;
var index_title = -1;
var index_content = -1;
var first_occur = -1;
// only match articles with not empty contents
if (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;
// 0x04. perform local searching
dataList.forEach(function(data) {
var isMatch = true;
if (!data.title || data.title.trim() === '') {
data.title = 'Untitled';
}
var orig_data_title = data.title.trim();
var data_title = orig_data_title.toLowerCase();
var orig_data_content = data.content.trim().replace(/<[^>]+>/g, '');
var data_content = orig_data_content.toLowerCase();
var data_url = data.url;
var index_title = -1;
var index_content = -1;
var first_occur = -1;
// only match articles with not empty contents
if (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;
}
//content_index.push({index_content:index_content, keyword_len:keyword_len});
}
if (i === 0) {
first_occur = index_content;
});
} else {
isMatch = false;
}
// 0x05. show search results
if (isMatch) {
resultHTML += '<a href=\'' + data_url + '\' class=\'list-group-item list-group-item-action font-weight-bolder search-list-title\'>' + orig_data_title + '</a>';
var content = orig_data_content;
if (first_occur >= 0) {
// cut out 100 characters
var start = first_occur - 20;
var end = first_occur + 80;

if (start < 0) {
start = 0;
}
//content_index.push({index_content:index_content, keyword_len:keyword_len});
}
});
} else {
isMatch = false;
}
// 0x05. show search results
if (isMatch) {
str += '<a href=\'' + data_url + '\' class=\'list-group-item list-group-item-action font-weight-bolder search-list-title\'>' + orig_data_title + '</a>';
var content = orig_data_content;
if (first_occur >= 0) {
// cut out 100 characters
var start = first_occur - 20;
var end = first_occur + 80;

if (start < 0) {
start = 0;
}

if (start === 0) {
end = 100;
}
if (start === 0) {
end = 100;
}

if (end > content.length) {
end = content.length;
}
if (end > content.length) {
end = content.length;
}

var match_content = content.substring(start, end);
var match_content = content.substring(start, end);

// highlight all keywords
keywords.forEach(function(keyword) {
var regS = new RegExp(keyword, 'gi');
match_content = match_content.replace(regS, '<span class="search-word">' + keyword + '</span>');
});
// highlight all keywords
keywords.forEach(function(keyword) {
var regS = new RegExp(keyword, 'gi');
match_content = match_content.replace(regS, '<span class="search-word">' + keyword + '</span>');
});

str += '<p class=\'search-list-content\'>' + match_content + '...</p>';
resultHTML += '<p class=\'search-list-content\'>' + match_content + '...</p>';
}
}
});
if (resultHTML.indexOf('list-group-item') === -1) {
return $input.addClass('invalid').removeClass('valid');
}
$input.addClass('valid').removeClass('invalid');
$result.html(resultHTML);
});
const input = jQuery('#local-search-input');
if (str.indexOf('list-group-item') === -1) {
return input.addClass('invalid').removeClass('valid');
}
input.addClass('valid').removeClass('invalid');
$resultContent.innerHTML = str;
});
}
});
}

function localSearchReset(searchSelector, resultSelector) {
'use strict';
var $input = jQuery(searchSelector);
var $result = jQuery(resultSelector);

if ($input.length === 0) {
// eslint-disable-next-line no-console
throw Error('No element selected by the searchSelector');
}
if ($result.length === 0) {
// eslint-disable-next-line no-console
throw Error('No element selected by the resultSelector');
}
});

jQuery('#local-search-close').on('click', function() {
jQuery('#local-search-input').val('').removeClass('invalid').removeClass('valid');
jQuery('#local-search-result').html('');
$input.val('').removeClass('invalid').removeClass('valid');
$result.html('');
}

var modal = jQuery('#modalSearch');
var searchSelector = '#local-search-input';
var resultSelector = '#local-search-result';
modal.on('show.bs.modal', function() {
var path = CONFIG.search_path || '/local-search.xml';
localSearchFunc(path, searchSelector, resultSelector);
});
modal.on('shown.bs.modal', function() {
jQuery('#local-search-input').focus();
});
modal.on('hidden.bs.modal', function() {
localSearchReset(searchSelector, resultSelector);
});
};
})();

0 comments on commit 4a0cc42

Please sign in to comment.