为 Jekyll 站点添加搜索功能

2016-03-29 AnnatarHe 更多博文 » 博客 » GitHub »

github js

原文链接 https://annatarhe.github.io/2016/03/29/add-search-function-at-github-pages.html
注:以下为加速网络访问所做的原文缓存,经过重新格式化,可能存在格式方面的问题,或偶有遗漏信息,请以原文为准。


随着文章越写越多,页数也随之增加,可是想找到一篇文章的难度有了很大的提升。

本篇介绍我自己做的搜索功能,通过js实现。

你也可以打开dev tools查看本页面的js代码。source map已开。

搜索框

首先添加搜索框,我的实现是在navbar添加一个搜索链接,点击会滑出搜索页面,设计功力有限,页面特别丑 T_T

那么余下的是事件的绑定,略去不说,有兴趣的看一下我的事件绑定

原理

原理很简单,通过在页面上添加js代码,jekyll吐出所有文章数据,形成一个数据源,然后通过input事件触发搜索,遍历对象。然后渲染即可。

数据源

我是写在了footer.html中。每个页面都会引用此模块,所以搜索功能在所有页面中都可以调用。

点击这里查看

搜索渲染

核心代码是search.js,打开dev tools看看。

{% highlight js %} function handleSearcher() { new Promise((resolve, reject) => { let searchVal = searchText.value.toLowerCase().trim() let res = posts.filter((item) => { return (item.title.toLowerCase().indexOf(searchVal) > 0) || (item.url.toLowerCase().indexOf(searchVal) > 0) }) resolve(res) }) .then(res => { // contact the dom string let domStr = '' for (let post of res ) { domStr += <li> <a href="${post.url}"> <span class="title">${post.title}</span> <span class="url">${post.url}</span> </a> </li> } return domStr }) .then(domStr => { // render it! resultDom.innerHTML = domStr }) } {% endhighlight %}

其实很简单,通过Promise分成了三块。

搜索

{% highlight js %} let searchVal = searchText.value.toLowerCase().trim() let res = posts.filter((item) => { return (item.title.toLowerCase().indexOf(searchVal) > 0) || (item.url.toLowerCase().indexOf(searchVal) > 0) }) resolve(res) {% endhighlight %}

首先对输入数据处理一下,小写,去空格。

然后用filter遍历,只要存在输入关键字就进行下一步。

构造DOM

因为上一步的结果传过来的是数组,所以这里遍历,同时构造DOM树。

没有用createElement的原因在于性能。重复创建100个DOM树所消耗的资源比字符串操作可要大多了。

渲染

上一步传过来了构造好的DOM string,这一步就是渲染。我非常粗暴的在父DOM里直接resultDom.innerHTML = domStr

原因依旧在于性能。直接放进去会自动一次性解析DOM树,要比一次次appendChild快多了。

问题

你也看到了,问题在于我用了太多的ES2015特性而没有编译什么的。兼容性满打满算也就支持到chrome 48左右。

input事件触发的可能太频繁导致一些性能问题。

不过,我的博客而已,不用现代浏览器的我也不欢迎。