最近一直在折腾Hxeo的站点,发现自带的主题吗,没有搜索功能。决定自己改一个。

感谢 @bay1 大佬的文章,原文链接:https://segmentfault.com/a/1190000011917419

下面就是在hexo主题添加本地搜索功能的过程。

生成搜索索引文件

hexo-generator-searchdb插件可以生成一个xml格式的索引文件。之后再利用jQuery的ajax函数查询并处理生成的索引文件。

获取 hexo-generator-searchdb 插件

npm install hexo-generator-searchdb --save

修改 hexo 全局配置文件

在 hexo 全局配置文件_config.yml最后添加下面的配置。

search:
  path: search.xml
  field: post
  format: html
  limit: 10000

添加搜索配置

生成配置文件

执行 Hexo 生成命令

hexo generate

生成的xml格式索引文件


添加js的搜索功能

html代码

<div id="site_search" class="search">
		<input type="text" id="local-search-input" class="search-input" placeholder="你想找些什么?" />
	    <div id="local-search-result" class="local-search-result"></div>
	</div>

js代码

//搜搜
	var searchFunc = function(path, search_id, content_id) {
		'use strict'; //使用严格模式
		$.ajax({
			url: path,
			dataType: "xml",
			success: function( xmlResponse ) {
				// 从xml中获取相应的标题等数据
				var datas = $( "entry", xmlResponse ).map(function() {
					return {
						title: $( "title", this ).text(),
						content: $("content",this).text(),
						url: $( "url" , this).text()
					};
				}).get();
				//ID选择器
				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;
					}
					// 本地搜索主要部分
					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;
						// 只匹配非空文章
						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) {
						//结果标签
							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) {
								// 拿出含有搜索字的部分
								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); 
								// 列出搜索关键字,定义class加高亮
								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;
				})
			}
		})
	};
	var path = "/search.xml";
	if(document.getElementById('local-search-input') !== null){
		searchFunc(path, 'local-search-input', 'local-search-result');
	}

然后自己添加样式就行

  • .search {整体样式}
  • .search .search-input {搜索框样式}
  • .search .search-input[type=text]:focus{搜索框得到焦点样式}
  • .search .local-search-result {搜索结果样式}
  • .search .search-result-list {搜索结果列表样式}
  • .search .search-result-title {搜索结果标题样式}
  • .search .search-result {搜索结果内容样式}
  • .search .search-keyword {关键字样式}
  • .search li {li样式}

效果如下

hexo本地搜索页面