ExSearch - 为Typecho带来实时搜索体验的插件

这款Typecho插件能够有效的加强Typecho的搜索体验,给您的访客门一个舒适的搜索体验。

Type­cho 中没有单独的搜索页,绝大多数主题的所谓「搜索页」只是为搜索框单独写了一个样式,具体的搜索还是靠页面跳转。我对 Type­cho 的搜索从来没有满意过,因此这次我想办法将其增强。

我需要为 Type­cho 添加搜索实时响应、高亮与预览功能。泽泽的搜索插件通过 hack Type­cho 的内部方法实现了高亮与过滤功能,但是仍然不能实现实时响应。其实也能理解,如果跟随输入实时响应的话,数据库的压力大大增加,而且网络压力也大大增加。必须另辟蹊径。

Hexo 这样无后端的博客为我提供了新的思路:将内容静态化,使搜索在前端进行。这样不仅降低了数据库压力,节省了网络请求数,同时也不用与 Type­cho 的内部方法作斗争。唯一的缺点是对内容过多的站点来说需要传输一定数量的内容到前端,但这通过缓存静态化与前端长缓存也能缓解。

ExSearch - 为Typecho带来实时搜索体验的插件-Npcink

使用

  • 下载页底提供的文件
  • 解压文件夹,并将文件夹重命名为 ExSearch
  • 上传至插件目录,在后台启用
  • 保存一次插件设置,并点击重建索引。

在主题中,在任何可点击的元素上加上 class="search-form-input",点击即可唤起搜索框。

自定义 hook

默认的,点击搜索结果时会直接跳转至对应的页面,但是若你的主题使用了 AJAX 或者 PJAX 技术,你可能需要使用自定义的钩子来处理点击事件(例如发起一次 PJAX 操作)。在页面中插入一个函数如下:

<script>
function ExSearchCall(item){
    // your code
}
</script>

其中,item 是一个 JQuery 对象。举例:

function ExSearchCall(item){
    if (item && item.length) {
        $('.ins-close').click(); // 关闭搜索框
        let url = item.attr('data-url'); // 获取目标页面 URL
        $.pjax({url: url, 
            container: '#pjax-container',
            fragment: '#pjax-container',
            timeout: 8000, }); // 发起一次 PJAX 请求
    }
}

可能的问题

如果你的站点内容过多导致建立索引失败,请在 Plugin.php 第 136 行左右的位置,取消下面两行的注释:

$sql = 'SET GLOBAL max_allowed_packet=4294967295;';
$db->query($sql);

注意,这需要高级权限。你也可以手动对数据库执行:

mysql > SET GLOBAL max_allowed_packet=4294967295;

Credit

本项目灵感来源于 Wikitten 与 PPOffice,感谢。

补充:

插件具体的实现原理是:

  1. 插件中生成整个数据库文章的json数据(并使用typecho的钩子可以保证在发表新文章、修改文章中时候同步更新数据),这个数据有两种方式存储(文件形式,数据库)
  2. 博客打开的时候就会加载到这个json数据到前端
  3. 搜索的时候直接拿这个json数据进行匹配就可以了

但我把代码用到我的博客上的时候,出现了一些问题。


当文章数目很多的时候(我的博客目前是217篇文章),生成的json数据大小是很大的,我生成之后是1.9M的大小,使用jquery的 getjson方法很耗时(我测试是19s,和服务器有关,虽然不阻碍页面渲染)

于是产生两个问题:

  1. 在json数据在请求的这个过程中,搜索功能是没办法用的
  2. json数据过大造成的流量问题

熊猫小A是一打开博客就开始请求这个json文件,我个人觉得搜索其实并不是一个常用功能,所以我是点击搜索框才开始请求这个json数据)


当然上面两个问题不是特别大的问题。

但是如果你的博客的文章非常之多!这个json数据会很大,导致的请求读取时间就可能非常长了,而且造成不必要的流量加载。


我的解决方法是:前端不要一次性加载整个文章的json数据,而是通过php使用SEESION变量存储读取缓存的json数据

if ($_SESSION['search_cache'] === false){
            $object['status'] = false;
            //这部分如果数据是存储在数据库中,就从数据库中读取,我这里是从缓存文件中读取
            $filePath = __TYPECHO_ROOT_DIR__ . __TYPECHO_PLUGIN_DIR__ . DIRECTORY_SEPARATOR.'Handsome'.DIRECTORY_SEPARATOR.'cache'.DIRECTORY_SEPARATOR.'search.json';
            $file = file_get_contents($filePath);
            if ($file === false){
                $fail = "{}";
                $_SESSION['search_cache'] = $fail;
                echo $fail;
            }else{
                $_SESSION['search_cache'] = $file;
            }
        }else{
            $object['status'] = true;
        }
        
        //处理搜索数据,返回结果
        ...

通过监控输入框的值,不断发起ajax请求,后端直接使用SEESION变量的值进行返回结果就可以。

优点: 多次搜索,只需要一次读取文件的消耗(之后使用SEESION变量)
缺点: 多次搜索会有多次ajax请求(但这个ajax请求不会读数据库,也不会读文件,总体来说消耗是非常小的,所以速度也是很快的)

(之前实现也是监控输入值发起ajax请求,只不过每次ajax请求都会操作数据库,这个速度很慢)

当然这种方法也只是一种权衡罢了,毕竟ajax请求再快也会受服务器是否阻塞和网络原因影响,而一开始就加载好全部的json数据则真正达到“即时搜索”。

关于搜索的问题,也许这个Typecho插件能够帮助到您:

ExSearch - 为Typecho带来实时搜索体验的插件-Npcink
ExSearch - 为Typecho带来实时搜索体验的插件-Npcink

Soso - 搜索增强Typecho插件

这款typecho插件可以增强Typecho的搜索功能,很是实用,还可以根据分类来搜索,很方便,是一款值得tu

下载权限

查看
  • 免费下载
    评论后下载
    登录后下载

  • {{attr.name}}:
您当前的等级为
您有每天免费下载所有资源次的特权,今日剩余 已取得下载权限
Typecho

Hermit - 文字类Typecho博客主题

2020-4-1 14:41:20

Typecho

DoubanBoard - 显示豆瓣书单的Typecho插件

2020-4-1 16:49:13

⚠️
Npcink上的部份代码及教程来源于互联网,仅供网友学习交流,若您喜欢本文可附上原文链接随意转载。
无意侵害您的权益,请发送邮件至 link@baimu.org 或点击右侧 私信:Muze 反馈,我们将尽快处理。
0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索