Hexo 主题简单实现搜索功能

warning: 这篇文章距离上次修改已过1507天,其中的内容可能已经有所变动。

最近一直在折腾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格式索引文件生成的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本地搜索页面hexo本地搜索页面

评论已关闭