feat: 本地搜索支持顯示文章內容和高亮keyword

🐛 fix: 修復搜索結果在手機端無法滾動的bug
🐛 fix: 修復aside categories 查看更多跳轉到tags頁面的bug closes #188
This commit is contained in:
Jerry
2020-04-07 14:24:11 +08:00
Unverified
parent 6c68ce1c4c
commit e81a81c9d1
5 changed files with 69 additions and 10 deletions

View File

@@ -18,7 +18,7 @@ hexo.extend.helper.register('aside_categories', function (categories, options) {
const depth = options.depth ? parseInt(options.depth, 10) : 0 const depth = options.depth ? parseInt(options.depth, 10) : 0
const orderby = options.orderby || 'name' const orderby = options.orderby || 'name'
const order = options.order || 1 const order = options.order || 1
const tagDir = this.url_for(config.tag_dir) const categoryDir = this.url_for(config.category_dir)
const limit = options.limit === 0 ? categories.length : options.limit const limit = options.limit === 0 ? categories.length : options.limit
const buttonLabel = this._p('aside.more_button') const buttonLabel = this._p('aside.more_button')
const prepareQuery = parent => { const prepareQuery = parent => {
@@ -74,7 +74,7 @@ hexo.extend.helper.register('aside_categories', function (categories, options) {
var moreHtml = '' var moreHtml = ''
if (categories.length <= limit) return '' if (categories.length <= limit) return ''
moreHtml += '<li class="aside-category-list-item is-center">' moreHtml += '<li class="aside-category-list-item is-center">'
moreHtml += `<a class="aside-category-list-item-more" href="${tagDir}" >` moreHtml += `<a class="aside-category-list-item-more" href="${categoryDir}" >`
moreHtml += buttonLabel moreHtml += buttonLabel
moreHtml += '</a></li>' moreHtml += '</a></li>'
return moreHtml return moreHtml

View File

@@ -50,4 +50,5 @@
height: 100% height: 100%
.search-result-list .search-result-list
max-height: 100% !important max-height: 75vh !important
padding-bottom: 2rem

View File

@@ -18,7 +18,8 @@
.local-search__hit-item .local-search__hit-item
position: relative position: relative
padding-left: 1.5rem padding-left: 1.3rem
line-height: 1.7
&:hover &:hover
&:before &:before
@@ -27,7 +28,7 @@
&:before &:before
$w = .3rem $w = .3rem
position: absolute position: absolute
top: .4rem top: .3rem
left: 0 left: 0
width: w = $w width: w = $w
height: h = w height: h = w
@@ -41,12 +42,20 @@
a a
display: block display: block
color: $font-black color: $font-black
font-weight: 600
font-size: 14px font-size: 14px
cursor: pointer cursor: pointer
&:hover &:hover
color: $search-color color: $search-color
.search-result
margin: 0 0 .4rem
.search-keyword
color: $search-keyword-highlight
font-weight: bold
.local-search-stats__hr .local-search-stats__hr
display: none !important display: none !important

View File

@@ -79,6 +79,7 @@ $reward-pop-up-color = #858585
// search // search
$search-bg = #f6f8fa $search-bg = #f6f8fa
$search-color = $theme-color $search-color = $theme-color
$search-keyword-highlight = #F47466
//gallery //gallery
$gallery-color = #fff $gallery-color = #fff
// tag-hide // tag-hide

View File

@@ -1,7 +1,10 @@
$(function () { $(function () {
var loadFlag = false var loadFlag = false
$('a.social-icon.search').on('click', function () { $('a.social-icon.search').on('click', function () {
$('body').css({ width: '100%', overflow: 'hidden' }) $('body').css({
width: '100%',
overflow: 'hidden'
})
$('.search-dialog').css('display', 'block') $('.search-dialog').css('display', 'block')
$('#local-search-input input').focus() $('#local-search-input input').focus()
$('.search-mask').fadeIn() $('.search-mask').fadeIn()
@@ -52,6 +55,7 @@ $(function () {
url: $('url', this).text() url: $('url', this).text()
} }
}).get() }).get()
var $input = $('#local-search-input input')[0] var $input = $('#local-search-input input')[0]
var $resultContent = $('#local-hits')[0] var $resultContent = $('#local-hits')[0]
$input.addEventListener('input', function () { $input.addEventListener('input', function () {
@@ -66,13 +70,17 @@ $(function () {
// perform local searching // perform local searching
datas.forEach(function (data) { datas.forEach(function (data) {
var isMatch = true var isMatch = true
if (!data.title || data.title.trim() === '') {
data.title = 'Untitled'
}
var dataTitle = data.title.trim().toLowerCase() var dataTitle = data.title.trim().toLowerCase()
var dataContent = data.content.trim().replace(/<[^>]+>/g, '').toLowerCase() var dataContent = data.content.trim().replace(/<[^>]+>/g, '').toLowerCase()
var dataUrl = data.url var dataUrl = data.url
var indexTitle = -1 var indexTitle = -1
var indexContent = -1 var indexContent = -1
var firstOccur = -1
// only match artiles with not empty titles and contents // only match artiles with not empty titles and contents
if (dataTitle !== '' && dataContent !== '') { if (dataTitle !== '' || dataContent !== '') {
keywords.forEach(function (keyword, i) { keywords.forEach(function (keyword, i) {
indexTitle = dataTitle.indexOf(keyword) indexTitle = dataTitle.indexOf(keyword)
indexContent = dataContent.indexOf(keyword) indexContent = dataContent.indexOf(keyword)
@@ -82,20 +90,60 @@ $(function () {
if (indexContent < 0) { if (indexContent < 0) {
indexContent = 0 indexContent = 0
} }
if (i === 0) {
firstOccur = indexContent
}
} }
}) })
} else {
isMatch = false
} }
// show search results // show search results
if (isMatch) { if (isMatch) {
str += '<div class="local-search__hit-item"><a href="' + dataUrl + '" class="search-result-title">' + dataTitle + '</a>' + '</div>' var content = data.content.trim().replace(/<[^>]+>/g, '')
if (firstOccur >= 0) {
// cut out 130 characters
var start = firstOccur - 30
var end = firstOccur + 100
if (start < 0) {
start = 0
}
if (start === 0) {
end = 100
}
if (end > content.length) {
end = content.length
}
var matchContent = content.substring(start, end)
// highlight all keywords
keywords.forEach(function (keyword) {
var regS = new RegExp(keyword, 'gi')
matchContent = matchContent.replace(regS, '<span class="search-keyword">' + keyword + '</span>')
dataTitle = dataTitle.replace(regS, '<span class="search-keyword">' + keyword + '</span>')
})
str += '<div class="local-search__hit-item"><a href="' + dataUrl + '" class="search-result-title">' + dataTitle + '</a>'
count += 1 count += 1
$('.local-search-stats__hr').show() $('.local-search-stats__hr').show()
if (dataContent !== '') {
str += '<p class="search-result">' + matchContent + '...</p>'
}
}
str += '</div>'
} }
}) })
if (count === 0) { if (count === 0) {
str += '<div id="local-search__hits-empty">' + GLOBAL_CONFIG.localSearch.languages.hits_empty.replace(/\$\{query}/, this.value.trim()) + str += '<div id="local-search__hits-empty">' + GLOBAL_CONFIG.localSearch.languages.hits_empty.replace(/\$\{query}/, this.value.trim()) +
'</div>' '</div>'
} }
str += '</div>'
$resultContent.innerHTML = str $resultContent.innerHTML = str
}) })
} }