mirror of
https://github.com/jerryc127/hexo-theme-butterfly.git
synced 2026-04-12 22:17:06 +08:00
本地搜索使用json替换xml,速度更快
## xml文件格式本地测试  ## json文件本地测试  ## json文件线上测试  ## 模式切换 两种模式 切换 只需要修改全局配置文件的搜索插件文件格式(json/xml)
This commit is contained in:
@@ -10,7 +10,7 @@ window.addEventListener('load', () => {
|
|||||||
loadFlag = true
|
loadFlag = true
|
||||||
}
|
}
|
||||||
// shortcut: ESC
|
// shortcut: ESC
|
||||||
document.addEventListener('keydown', function f (event) {
|
document.addEventListener('keydown', function f(event) {
|
||||||
if (event.code === 'Escape') {
|
if (event.code === 'Escape') {
|
||||||
closeSearch()
|
closeSearch()
|
||||||
document.removeEventListener('keydown', f)
|
document.removeEventListener('keydown', f)
|
||||||
@@ -41,107 +41,112 @@ window.addEventListener('load', () => {
|
|||||||
searchClickFn()
|
searchClickFn()
|
||||||
})
|
})
|
||||||
|
|
||||||
function search (path) {
|
async function search(path) {
|
||||||
fetch(GLOBAL_CONFIG.root + path)
|
let datas = []
|
||||||
.then(response => response.text())
|
const typeF = path.split('.')[1]
|
||||||
.then(str => new window.DOMParser().parseFromString(str, 'text/xml'))
|
const response = await fetch(GLOBAL_CONFIG.root + path)
|
||||||
.then(data => {
|
if (typeF === 'json') {
|
||||||
const datas = [...data.querySelectorAll('entry')].map(function (item) {
|
datas = await response.json()
|
||||||
const content = item.querySelector('content')
|
} else if (typeF === 'xml') {
|
||||||
return {
|
let res = await response.text()
|
||||||
title: item.querySelector('title').textContent,
|
let t = await new window.DOMParser().parseFromString(res, 'text/xml')
|
||||||
content: content ? content.textContent : '',
|
let a = await t
|
||||||
url: item.querySelector('url').textContent
|
datas = [...a.querySelectorAll('entry')].map(function (item) {
|
||||||
}
|
return {
|
||||||
})
|
title: item.querySelector('title').textContent,
|
||||||
|
content: item.querySelector('content').textContent,
|
||||||
const $input = document.querySelector('#local-search-input input')
|
url: item.querySelector('url').textContent
|
||||||
const $resultContent = document.getElementById('local-search-results')
|
}
|
||||||
$input.addEventListener('input', function () {
|
})
|
||||||
let str = '<div class="search-result-list">'
|
}
|
||||||
const keywords = this.value.trim().toLowerCase().split(/[\s]+/)
|
const $input = document.querySelector('#local-search-input input')
|
||||||
$resultContent.innerHTML = ''
|
const $resultContent = document.getElementById('local-search-results')
|
||||||
if (this.value.trim().length <= 0) return
|
$input.addEventListener('input', function () {
|
||||||
let count = 0
|
let str = '<div class="search-result-list">'
|
||||||
// perform local searching
|
const keywords = this.value.trim().toLowerCase().split(/[\s]+/)
|
||||||
datas.forEach(function (data) {
|
$resultContent.innerHTML = ''
|
||||||
let isMatch = true
|
if (this.value.trim().length <= 0) return
|
||||||
if (!data.title || data.title.trim() === '') {
|
let count = 0
|
||||||
data.title = 'Untitled'
|
// perform local searching
|
||||||
}
|
datas.forEach(function (data) {
|
||||||
let dataTitle = data.title.trim().toLowerCase()
|
let isMatch = true
|
||||||
const dataContent = data.content.trim().replace(/<[^>]+>/g, '').toLowerCase()
|
if (!data.title || data.title.trim() === '') {
|
||||||
const dataUrl = data.url.startsWith('/') ? data.url : GLOBAL_CONFIG.root + data.url
|
data.title = 'Untitled'
|
||||||
let indexTitle = -1
|
}
|
||||||
let indexContent = -1
|
let dataTitle = data.title.trim().toLowerCase()
|
||||||
let firstOccur = -1
|
const dataContent = data.content.trim().replace(/<[^>]+>/g, '').toLowerCase()
|
||||||
// only match artiles with not empty titles and contents
|
const dataUrl = data.url.startsWith('/') ? data.url : GLOBAL_CONFIG.root + data.url
|
||||||
if (dataTitle !== '' || dataContent !== '') {
|
let indexTitle = -1
|
||||||
keywords.forEach(function (keyword, i) {
|
let indexContent = -1
|
||||||
indexTitle = dataTitle.indexOf(keyword)
|
let firstOccur = -1
|
||||||
indexContent = dataContent.indexOf(keyword)
|
// only match artiles with not empty titles and contents
|
||||||
if (indexTitle < 0 && indexContent < 0) {
|
if (dataTitle !== '' || dataContent !== '') {
|
||||||
isMatch = false
|
keywords.forEach(function (keyword, i) {
|
||||||
} else {
|
indexTitle = dataTitle.indexOf(keyword)
|
||||||
if (indexContent < 0) {
|
indexContent = dataContent.indexOf(keyword)
|
||||||
indexContent = 0
|
if (indexTitle < 0 && indexContent < 0) {
|
||||||
}
|
|
||||||
if (i === 0) {
|
|
||||||
firstOccur = indexContent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
isMatch = false
|
isMatch = false
|
||||||
}
|
} else {
|
||||||
|
if (indexContent < 0) {
|
||||||
// show search results
|
indexContent = 0
|
||||||
if (isMatch) {
|
}
|
||||||
const content = data.content.trim().replace(/<[^>]+>/g, '')
|
if (i === 0) {
|
||||||
if (firstOccur >= 0) {
|
firstOccur = indexContent
|
||||||
// cut out 130 characters
|
|
||||||
let start = firstOccur - 30
|
|
||||||
let end = firstOccur + 100
|
|
||||||
|
|
||||||
if (start < 0) {
|
|
||||||
start = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
if (start === 0) {
|
|
||||||
end = 100
|
|
||||||
}
|
|
||||||
|
|
||||||
if (end > content.length) {
|
|
||||||
end = content.length
|
|
||||||
}
|
|
||||||
|
|
||||||
let matchContent = content.substring(start, end)
|
|
||||||
|
|
||||||
// highlight all keywords
|
|
||||||
keywords.forEach(function (keyword) {
|
|
||||||
const 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
|
|
||||||
|
|
||||||
if (dataContent !== '') {
|
|
||||||
str += '<p class="search-result">' + matchContent + '...</p>'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
str += '</div>'
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if (count === 0) {
|
} else {
|
||||||
str += '<div id="local-search__hits-empty">' + GLOBAL_CONFIG.localSearch.languages.hits_empty.replace(/\$\{query}/, this.value.trim()) +
|
isMatch = false
|
||||||
'</div>'
|
}
|
||||||
|
|
||||||
|
// show search results
|
||||||
|
if (isMatch) {
|
||||||
|
const content = data.content.trim().replace(/<[^>]+>/g, '')
|
||||||
|
if (firstOccur >= 0) {
|
||||||
|
// cut out 130 characters
|
||||||
|
// let start = firstOccur - 30 < 0 ? 0 : firstOccur - 30
|
||||||
|
// let end = firstOccur + 50 > content.length ? content.length : firstOccur + 50
|
||||||
|
let start = firstOccur - 30
|
||||||
|
let end = firstOccur + 100
|
||||||
|
|
||||||
|
if (start < 0) {
|
||||||
|
start = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start === 0) {
|
||||||
|
end = 100
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end > content.length) {
|
||||||
|
end = content.length
|
||||||
|
}
|
||||||
|
|
||||||
|
let matchContent = content.substring(start, end)
|
||||||
|
|
||||||
|
// highlight all keywords
|
||||||
|
keywords.forEach(function (keyword) {
|
||||||
|
const 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
|
||||||
|
|
||||||
|
if (dataContent !== '') {
|
||||||
|
str += '<p class="search-result">' + matchContent + '...</p>'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
str += '</div>'
|
str += '</div>'
|
||||||
$resultContent.innerHTML = str
|
}
|
||||||
window.pjax && window.pjax.refresh($resultContent)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
if (count === 0) {
|
||||||
|
str += '<div id="local-search__hits-empty">' + GLOBAL_CONFIG.localSearch.languages.hits_empty.replace(/\$\{query}/, this.value.trim()) +
|
||||||
|
'</div>'
|
||||||
|
}
|
||||||
|
str += '</div>'
|
||||||
|
$resultContent.innerHTML = str
|
||||||
|
window.pjax && window.pjax.refresh($resultContent)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user