:::success
在最新的 5.0 版本已经支持拼音搜索,请升级体验
本篇文章直击如何使到 icarus 升级到可以支持拼音搜索
前期准备
- Icarus 主题版本 3.0 以上
- 搜索插件使用的是 Insight
操作方法
- 另存为下面的文件到
themes/icarus/source/js
pinyin.js
- 另存为下面的文件到
themes/icarus/layout/search
insight.jsx
- 另存为下面的文件到
themes/icarus/source/js
insight.js
- 修改
themes/icarus/layout/search/insight.jsx,加入拼音检索开关和依赖的 pinyin.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| /** * Insight search plugin JSX component. * @module view/search/insight */
@@ -3,7 +3,7 @@ const { Component, Fragment } = require('inferno'); -const { cacheComponent } = require('../../util/cache'); +const { cacheComponent } = require('hexo-component-inferno/lib/util/cache');
/** * Algolia search engine JSX component. @@ -36,11 +36,18 @@ class Insight extends Component { <div class="searchbox-input-container"> <input type="text" class="searchbox-input" placeholder={translation.hint}/> </div> + <div class="searchbox-pinyin"> + <label class="checkbox"> + <input id="search-by-pinyin" type="checkbox" checked="checked"/> + <span> 拼音检索</span> + </label> + </div> <a class="searchbox-close" href="javascript:;">×</a> </div> <div class="searchbox-body"></div> </div> </div> + <script src="/js/pinyin.js" defer={true}></script> <script src={jsUrl} defer={true}></script> <script dangerouslySetInnerHTML={{ __html: js }}></script> </Fragment>;
|
- 修改
themes/icarus/source/js/insight.js,在原有匹配代码基础上增加拼音匹配代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
@@ -6,6 +6,19 @@ function loadInsight(config, translation) { // eslint-disable-line no-unused-var const $main = $('.searchbox'); const $input = $main.find('.searchbox-input'); const $container = $main.find('.searchbox-body'); + const $searchByPinyin = $main.find('#search-by-pinyin'); + + /** + * 查询匹配拼音的数据。性能低于普通匹配,如果未启用拼音检索模式,直接返回 false。 + * https://github.com/xmflswood/pinyin-match + * @param input {string} 目标字符串 + * @param keyword {string} 输入的拼音或其他关键词 + * @returns {[Array]|{Boolean}} 找到返回出现位置,未找到 / 未启用返回 false + */ + function pinyinMatch(input, keyword) { + if (!$searchByPinyin.prop("checked")) return false; + return PinyinMatch.match(input, keyword); + }
function section(title) { return $('<section>').addClass('searchbox-result-section').append($('<header>').text(title)); @@ -33,10 +46,12 @@ function loadInsight(config, translation) { // eslint-disable-line no-unused-var const testText = text.toLowerCase(); const indices = matches.map(match => { const index = testText.indexOf(match.toLowerCase()); - if (!match || index === -1) { - return null; + if (match && index !== -1) { + return [index, index + match.length]; } - return [index, index + match.length]; + // Search by pinyin + const pinyinIndex = pinyinMatch(testText, match.toLowerCase()); + return pinyinIndex ? [pinyinIndex[0], pinyinIndex[1] + 1] : null; }).filter(match => { return match !== null; }).sort((a, b) => { @@ -140,6 +155,8 @@ function loadInsight(config, translation) { // eslint-disable-line no-unused-var } if (obj[field].toLowerCase().indexOf(keyword) > -1) { return true; + } else if (pinyinMatch(obj[field].toLowerCase(), keyword)) { + return true; } return false; }); @@ -266,10 +283,12 @@ function loadInsight(config, translation) { // eslint-disable-line no-unused-var if (location.hash.trim() $main.addClass('show'); } - $input.on('input', function() { - const keywords = $(this).val(); + function onInputChange() { + const keywords = $input.val(); searchResultToDOM(keywords, search(json, keywords)); - }); + } + $input.on('input', onInputChange); + $searchByPinyin.on('change', onInputChange); $input.trigger('input'); });
|
- 修改
themes/icarus/include/style/search.styl,调整拼音检索复选框大小和位置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
|
@@ -96,6 +96,16 @@ $searchbox-bg-pagination-item-disabled ?= $searchbox-bg-container .searchbox-input flex-grow: 1 color: inherit box-sizing: border-box padding: .75em 0 .75em 1.25em background: $searchbox-bg-input
+ .searchbox-pinyin + display: flex + align-items: center + user-select: none + input + vertical-align: middle + span + position: relative + top: 1px + .searchbox-close display: inline-block font-size: 1.5em padding: .5em .75em cursor: pointer
|
致谢
感谢来自 ppoffice 的hexo-component-inferno 项目
以及 xmflswood 的 pinyin-match 项目提供支撑