mirror of
https://github.com/jerryc127/hexo-theme-butterfly.git
synced 2026-04-16 20:30:53 +08:00
feat: 替換 Justified Gallery 為 flickr-justified-gallery
feat: 完全移除 jquery feat: 清除配置文件的CDN, 默認 CDN 不再顯示在 config feat: 切換夜間模式後, mermaid 也會切換夜間主題 feat: 移除騰訊分析 feat: 移除右下角字體調整按鈕 feat: 本地搜索可處理 json feat: 右下角按鈕自定義順序 feat: 右小角按鈕 UI 微調 improvement: 手機端更改閲讀模式退出按鈕到右下角 improvement: photofigcaption 和 fancybox 的 figcaption 優先顯示 圖片的title屬性,然後是 alt 屬性 improvement: 首頁ui微調 improvement: 禁止一些瀏覽器會出現點擊左下角按鈕出現放大網頁的行為 improvement: js 優化 fix: 修復窗口大小改變時,導航欄的ui 可能會錯亂的 bug fix: 修復 pjax 下, twikoo 評論獲取是上一篇評論的 bug fix: 壓縮 html 代碼後, mermaid 顯示正常
This commit is contained in:
@@ -1,23 +1,21 @@
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const $blogName = document.getElementById('site-name')
|
||||
let blogNameWidth = $blogName && $blogName.offsetWidth
|
||||
const $menusEle = document.querySelector('#menus .menus_items')
|
||||
let menusWidth = $menusEle && $menusEle.offsetWidth
|
||||
const $searchEle = document.querySelector('#search-button')
|
||||
let searchWidth = $searchEle && $searchEle.offsetWidth
|
||||
let blogNameWidth, menusWidth, searchWidth, $nav, hideMenuIndex, mobileSidebarOpen
|
||||
|
||||
const adjustMenu = (change = false) => {
|
||||
if (change) {
|
||||
blogNameWidth = $blogName && $blogName.offsetWidth
|
||||
menusWidth = $menusEle && $menusEle.offsetWidth
|
||||
searchWidth = $searchEle && $searchEle.offsetWidth
|
||||
const adjustMenu = (init) => {
|
||||
if (init) {
|
||||
blogNameWidth = document.getElementById('site-name').offsetWidth
|
||||
const $menusEle = document.querySelectorAll('#menus .menus_item')
|
||||
menusWidth = 0
|
||||
$menusEle.length && $menusEle.forEach(i => { menusWidth += i.offsetWidth })
|
||||
const $searchEle = document.querySelector('#search-button')
|
||||
searchWidth = $searchEle ? $searchEle.offsetWidth : 0
|
||||
$nav = document.getElementById('nav')
|
||||
}
|
||||
const $nav = document.getElementById('nav')
|
||||
let t
|
||||
if (window.innerWidth < 768) t = true
|
||||
else t = blogNameWidth + menusWidth + searchWidth > $nav.offsetWidth - 120
|
||||
|
||||
if (t) {
|
||||
if (window.innerWidth < 768) hideMenuIndex = true
|
||||
else hideMenuIndex = blogNameWidth + menusWidth + searchWidth > $nav.offsetWidth - 120
|
||||
|
||||
if (hideMenuIndex) {
|
||||
$nav.classList.add('hide-menu')
|
||||
} else {
|
||||
$nav.classList.remove('hide-menu')
|
||||
@@ -26,44 +24,26 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
|
||||
// 初始化header
|
||||
const initAdjust = () => {
|
||||
adjustMenu()
|
||||
document.getElementById('nav').classList.add('show')
|
||||
adjustMenu(true)
|
||||
$nav.classList.add('show')
|
||||
}
|
||||
|
||||
// sidebar menus
|
||||
const sidebarFn = () => {
|
||||
const $toggleMenu = document.getElementById('toggle-menu')
|
||||
const $mobileSidebarMenus = document.getElementById('sidebar-menus')
|
||||
const $menuMask = document.getElementById('menu-mask')
|
||||
const $body = document.body
|
||||
|
||||
function openMobileSidebar () {
|
||||
const sidebarFn = {
|
||||
open: () => {
|
||||
btf.sidebarPaddingR()
|
||||
$body.style.overflow = 'hidden'
|
||||
btf.fadeIn($menuMask, 0.5)
|
||||
$mobileSidebarMenus.classList.add('open')
|
||||
}
|
||||
|
||||
function closeMobileSidebar () {
|
||||
document.body.style.overflow = 'hidden'
|
||||
btf.fadeIn(document.getElementById('menu-mask'), 0.5)
|
||||
document.getElementById('sidebar-menus').classList.add('open')
|
||||
mobileSidebarOpen = true
|
||||
},
|
||||
close: () => {
|
||||
const $body = document.body
|
||||
$body.style.overflow = ''
|
||||
$body.style.paddingRight = ''
|
||||
btf.fadeOut($menuMask, 0.5)
|
||||
$mobileSidebarMenus.classList.remove('open')
|
||||
btf.fadeOut(document.getElementById('menu-mask'), 0.5)
|
||||
document.getElementById('sidebar-menus').classList.remove('open')
|
||||
}
|
||||
|
||||
$toggleMenu.addEventListener('click', openMobileSidebar)
|
||||
|
||||
$menuMask.addEventListener('click', e => {
|
||||
if ($mobileSidebarMenus.classList.contains('open')) {
|
||||
closeMobileSidebar()
|
||||
}
|
||||
})
|
||||
|
||||
window.addEventListener('resize', e => {
|
||||
if (btf.isHidden($toggleMenu)) {
|
||||
if ($mobileSidebarMenus.classList.contains('open')) closeMobileSidebar()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -225,7 +205,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
function addPhotoFigcaption () {
|
||||
document.querySelectorAll('#article-container img').forEach(function (item) {
|
||||
const parentEle = item.parentNode
|
||||
const altValue = item.alt
|
||||
const altValue = item.title || item.alt
|
||||
if (altValue && !parentEle.parentNode.classList.contains('justified-gallery')) {
|
||||
const ele = document.createElement('div')
|
||||
ele.className = 'img-alt is-center'
|
||||
@@ -237,7 +217,6 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
|
||||
/**
|
||||
* Lightbox
|
||||
* It needs to call it after the Justified Gallery done, or the fancybox maybe not work
|
||||
*/
|
||||
const runLightbox = () => {
|
||||
btf.loadLightbox(document.querySelectorAll('#article-container img:not(.no-lightbox)'))
|
||||
@@ -245,41 +224,28 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
|
||||
/**
|
||||
* justified-gallery 圖庫排版
|
||||
* 需要 jQuery
|
||||
*/
|
||||
let detectJgJsLoad = false
|
||||
const runJustifiedGallery = function (ele) {
|
||||
const $justifiedGallery = $(ele)
|
||||
const $imgList = $justifiedGallery.find('img')
|
||||
$imgList.unwrap() // remove <p> tag
|
||||
if ($imgList.length) {
|
||||
$imgList.each(function (i, o) {
|
||||
if ($(o).attr('data-lazy-src')) $(o).attr('src', $(o).attr('data-lazy-src'))
|
||||
$(o).wrap('<div></div>')
|
||||
ele.forEach(item => {
|
||||
const $imgList = item.querySelectorAll('img')
|
||||
|
||||
$imgList.forEach(i => {
|
||||
const dataLazySrc = i.getAttribute('data-lazy-src')
|
||||
if (dataLazySrc) i.src = dataLazySrc
|
||||
btf.wrap(i, 'div', { class: 'fj-gallery-item' })
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
runLightbox()
|
||||
|
||||
if (detectJgJsLoad) {
|
||||
btf.initJustifiedGallery($justifiedGallery)
|
||||
if (window.fjGallery) {
|
||||
btf.initJustifiedGallery(ele)
|
||||
return
|
||||
}
|
||||
|
||||
$('head').append(`<link rel="stylesheet" type="text/css" href="${GLOBAL_CONFIG.source.justifiedGallery.css}">`)
|
||||
$.getScript(`${GLOBAL_CONFIG.source.justifiedGallery.js}`, () => { btf.initJustifiedGallery($justifiedGallery) })
|
||||
detectJgJsLoad = true
|
||||
}
|
||||
|
||||
const jqLoadAndRun = () => {
|
||||
const $jgEle = document.querySelectorAll('#article-container .justified-gallery')
|
||||
if ($jgEle.length) {
|
||||
btf.isJqueryLoad(() => {
|
||||
runJustifiedGallery($jgEle)
|
||||
})
|
||||
return
|
||||
}
|
||||
runLightbox()
|
||||
const newEle = document.createElement('link')
|
||||
newEle.rel = 'stylesheet'
|
||||
newEle.href = GLOBAL_CONFIG.source.justifiedGallery.css
|
||||
document.body.appendChild(newEle)
|
||||
getScript(`${GLOBAL_CONFIG.source.justifiedGallery.js}`).then(() => { btf.initJustifiedGallery(ele) })
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -328,7 +294,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
}
|
||||
$header.classList.add('nav-fixed')
|
||||
if (window.getComputedStyle($rightside).getPropertyValue('opacity') === '0') {
|
||||
$rightside.style.cssText = 'opacity: 1; transform: translateX(-38px)'
|
||||
$rightside.style.cssText = 'opacity: 0.7; transform: translateX(-58px)'
|
||||
}
|
||||
} else {
|
||||
if (currentTop === 0) {
|
||||
@@ -338,7 +304,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
}
|
||||
|
||||
if (document.body.scrollHeight <= innerHeight) {
|
||||
$rightside.style.cssText = 'opacity: 1; transform: translateX(-38px)'
|
||||
$rightside.style.cssText = 'opacity: 0.7; transform: translateX(-58px)'
|
||||
}
|
||||
}, 200)()
|
||||
}
|
||||
@@ -390,9 +356,9 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
}
|
||||
}
|
||||
|
||||
const mobileToc = {
|
||||
window.mobileToc = {
|
||||
open: () => {
|
||||
$cardTocLayout.style.cssText = 'animation: toc-open .3s; opacity: 1; right: 45px'
|
||||
$cardTocLayout.style.cssText = 'animation: toc-open .3s; opacity: 1; right: 55px'
|
||||
},
|
||||
|
||||
close: () => {
|
||||
@@ -403,11 +369,6 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById('mobile-toc-button').addEventListener('click', () => {
|
||||
if (window.getComputedStyle($cardTocLayout).getPropertyValue('opacity') === '0') mobileToc.open()
|
||||
else mobileToc.close()
|
||||
})
|
||||
|
||||
// toc元素點擊
|
||||
$cardToc.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
@@ -416,7 +377,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
: e.target.parentElement
|
||||
btf.scrollToDest(btf.getEleTop(document.getElementById(decodeURI($target.getAttribute('href')).replace('#', ''))), 300)
|
||||
if (window.innerWidth < 900) {
|
||||
mobileToc.close()
|
||||
window.mobileToc.close()
|
||||
}
|
||||
})
|
||||
|
||||
@@ -512,6 +473,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
typeof utterancesTheme === 'function' && utterancesTheme()
|
||||
typeof FB === 'object' && window.loadFBComment()
|
||||
window.DISQUS && document.getElementById('disqus_thread').children.length && setTimeout(() => window.disqusReset(), 200)
|
||||
typeof runMermaid === 'function' && window.runMermaid()
|
||||
},
|
||||
showOrHideBtn: () => { // rightside 點擊設置 按鈕 展開
|
||||
document.getElementById('rightside-config-hide').classList.toggle('show')
|
||||
@@ -527,22 +489,9 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
$htmlDom.toggle('hide-aside')
|
||||
},
|
||||
|
||||
adjustFontSize: (plus) => {
|
||||
const fontSizeVal = parseInt(window.getComputedStyle(document.documentElement).getPropertyValue('--global-font-size'))
|
||||
let newValue = ''
|
||||
if (plus) {
|
||||
if (fontSizeVal >= 20) return
|
||||
newValue = fontSizeVal + 1
|
||||
document.documentElement.style.setProperty('--global-font-size', newValue + 'px')
|
||||
!document.getElementById('nav').classList.contains('hide-menu') && adjustMenu(true)
|
||||
} else {
|
||||
if (fontSizeVal <= 10) return
|
||||
newValue = fontSizeVal - 1
|
||||
document.documentElement.style.setProperty('--global-font-size', newValue + 'px')
|
||||
document.getElementById('nav').classList.contains('hide-menu') && adjustMenu(true)
|
||||
}
|
||||
|
||||
saveToLocal.set('global-font-size', newValue, 2)
|
||||
runMobileToc: () => {
|
||||
if (window.getComputedStyle(document.getElementById('card-toc')).getPropertyValue('opacity') === '0') window.mobileToc.open()
|
||||
else window.mobileToc.close()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -555,6 +504,9 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
case 'rightside_config':
|
||||
rightSideFn.showOrHideBtn()
|
||||
break
|
||||
case 'mobile-toc-button':
|
||||
rightSideFn.runMobileToc()
|
||||
break
|
||||
case 'readmode':
|
||||
rightSideFn.switchReadMode()
|
||||
break
|
||||
@@ -564,12 +516,6 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
case 'hide-aside-btn':
|
||||
rightSideFn.hideAsideBtn()
|
||||
break
|
||||
case 'font-plus':
|
||||
rightSideFn.adjustFontSize(true)
|
||||
break
|
||||
case 'font-minus':
|
||||
rightSideFn.adjustFontSize()
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
@@ -659,8 +605,8 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
const $hideContent = $this.nextElementSibling
|
||||
$this.classList.toggle('open')
|
||||
if ($this.classList.contains('open')) {
|
||||
if ($hideContent.querySelectorAll('.justified-gallery').length > 0) {
|
||||
btf.initJustifiedGallery($hideContent.querySelectorAll('.justified-gallery'))
|
||||
if ($hideContent.querySelectorAll('.fj-gallery').length > 0) {
|
||||
btf.initJustifiedGallery($hideContent.querySelectorAll('.fj-gallery'))
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -686,7 +632,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
if (item.id === tabId) item.classList.add('active')
|
||||
else item.classList.remove('active')
|
||||
})
|
||||
const $isTabJustifiedGallery = $tabContent.querySelectorAll(`#${tabId} .justified-gallery`)
|
||||
const $isTabJustifiedGallery = $tabContent.querySelectorAll(`#${tabId} .fj-gallery`)
|
||||
if ($isTabJustifiedGallery.length > 0) {
|
||||
btf.initJustifiedGallery($isTabJustifiedGallery)
|
||||
}
|
||||
@@ -776,8 +722,12 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
}
|
||||
|
||||
const unRefreshFn = function () {
|
||||
window.addEventListener('resize', adjustMenu)
|
||||
window.addEventListener('orientationchange', () => { setTimeout(adjustMenu(true), 100) })
|
||||
window.addEventListener('resize', () => {
|
||||
adjustMenu(false)
|
||||
hideMenuIndex && mobileSidebarOpen && sidebarFn.close()
|
||||
})
|
||||
|
||||
document.getElementById('menu-mask').addEventListener('click', e => { sidebarFn.close() })
|
||||
|
||||
clickFnOfSubMenu()
|
||||
GLOBAL_CONFIG.islazyload && lazyloadImg()
|
||||
@@ -798,17 +748,21 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
}
|
||||
|
||||
GLOBAL_CONFIG_SITE.isToc && tocFn()
|
||||
sidebarFn()
|
||||
GLOBAL_CONFIG_SITE.isHome && scrollDownInIndex()
|
||||
addHighlightTool()
|
||||
GLOBAL_CONFIG.isPhotoFigcaption && addPhotoFigcaption()
|
||||
jqLoadAndRun()
|
||||
scrollFn()
|
||||
|
||||
const $jgEle = document.querySelectorAll('#article-container .fj-gallery')
|
||||
$jgEle.length && runJustifiedGallery($jgEle)
|
||||
|
||||
runLightbox()
|
||||
addTableWrap()
|
||||
clickFnOfTagHide()
|
||||
tabsFn.clickFnOfTabs()
|
||||
tabsFn.backToTop()
|
||||
switchComments()
|
||||
document.getElementById('toggle-menu').addEventListener('click', () => { sidebarFn.open() })
|
||||
}
|
||||
|
||||
refreshFn()
|
||||
|
||||
@@ -41,107 +41,112 @@ window.addEventListener('load', () => {
|
||||
searchClickFn()
|
||||
})
|
||||
|
||||
function search (path) {
|
||||
fetch(GLOBAL_CONFIG.root + path)
|
||||
.then(response => response.text())
|
||||
.then(str => new window.DOMParser().parseFromString(str, 'text/xml'))
|
||||
.then(data => {
|
||||
const datas = [...data.querySelectorAll('entry')].map(function (item) {
|
||||
const content = item.querySelector('content')
|
||||
return {
|
||||
title: item.querySelector('title').textContent,
|
||||
content: content ? content.textContent : '',
|
||||
url: item.querySelector('url').textContent
|
||||
}
|
||||
})
|
||||
|
||||
const $input = document.querySelector('#local-search-input input')
|
||||
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]+/)
|
||||
$resultContent.innerHTML = ''
|
||||
if (this.value.trim().length <= 0) return
|
||||
let count = 0
|
||||
// perform local searching
|
||||
datas.forEach(function (data) {
|
||||
let isMatch = true
|
||||
if (!data.title || data.title.trim() === '') {
|
||||
data.title = 'Untitled'
|
||||
}
|
||||
let dataTitle = data.title.trim().toLowerCase()
|
||||
const dataContent = data.content.trim().replace(/<[^>]+>/g, '').toLowerCase()
|
||||
const dataUrl = data.url.startsWith('/') ? data.url : GLOBAL_CONFIG.root + data.url
|
||||
let indexTitle = -1
|
||||
let indexContent = -1
|
||||
let firstOccur = -1
|
||||
// only match artiles with not empty titles and contents
|
||||
if (dataTitle !== '' || dataContent !== '') {
|
||||
keywords.forEach(function (keyword, i) {
|
||||
indexTitle = dataTitle.indexOf(keyword)
|
||||
indexContent = dataContent.indexOf(keyword)
|
||||
if (indexTitle < 0 && indexContent < 0) {
|
||||
isMatch = false
|
||||
} else {
|
||||
if (indexContent < 0) {
|
||||
indexContent = 0
|
||||
}
|
||||
if (i === 0) {
|
||||
firstOccur = indexContent
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
async function search (path) {
|
||||
let datas = []
|
||||
const typeF = path.split('.')[1]
|
||||
const response = await fetch(GLOBAL_CONFIG.root + path)
|
||||
if (typeF === 'json') {
|
||||
datas = await response.json()
|
||||
} else if (typeF === 'xml') {
|
||||
const res = await response.text()
|
||||
const t = await new window.DOMParser().parseFromString(res, 'text/xml')
|
||||
const a = await t
|
||||
datas = [...a.querySelectorAll('entry')].map(function (item) {
|
||||
return {
|
||||
title: item.querySelector('title').textContent,
|
||||
content: item.querySelector('content').textContent,
|
||||
url: item.querySelector('url').textContent
|
||||
}
|
||||
})
|
||||
}
|
||||
const $input = document.querySelector('#local-search-input input')
|
||||
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]+/)
|
||||
$resultContent.innerHTML = ''
|
||||
if (this.value.trim().length <= 0) return
|
||||
let count = 0
|
||||
// perform local searching
|
||||
datas.forEach(function (data) {
|
||||
let isMatch = true
|
||||
if (!data.title || data.title.trim() === '') {
|
||||
data.title = 'Untitled'
|
||||
}
|
||||
let dataTitle = data.title.trim().toLowerCase()
|
||||
const dataContent = data.content.trim().replace(/<[^>]+>/g, '').toLowerCase()
|
||||
const dataUrl = data.url.startsWith('/') ? data.url : GLOBAL_CONFIG.root + data.url
|
||||
let indexTitle = -1
|
||||
let indexContent = -1
|
||||
let firstOccur = -1
|
||||
// only match artiles with not empty titles and contents
|
||||
if (dataTitle !== '' || dataContent !== '') {
|
||||
keywords.forEach(function (keyword, i) {
|
||||
indexTitle = dataTitle.indexOf(keyword)
|
||||
indexContent = dataContent.indexOf(keyword)
|
||||
if (indexTitle < 0 && indexContent < 0) {
|
||||
isMatch = false
|
||||
}
|
||||
|
||||
// show search results
|
||||
if (isMatch) {
|
||||
const content = data.content.trim().replace(/<[^>]+>/g, '')
|
||||
if (firstOccur >= 0) {
|
||||
// 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>'
|
||||
}
|
||||
} else {
|
||||
if (indexContent < 0) {
|
||||
indexContent = 0
|
||||
}
|
||||
if (i === 0) {
|
||||
firstOccur = indexContent
|
||||
}
|
||||
str += '</div>'
|
||||
}
|
||||
})
|
||||
if (count === 0) {
|
||||
str += '<div id="local-search__hits-empty">' + GLOBAL_CONFIG.localSearch.languages.hits_empty.replace(/\$\{query}/, this.value.trim()) +
|
||||
'</div>'
|
||||
} else {
|
||||
isMatch = false
|
||||
}
|
||||
|
||||
// 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>'
|
||||
$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)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@@ -72,20 +72,6 @@ const btf = {
|
||||
})
|
||||
},
|
||||
|
||||
initJustifiedGallery: function (selector) {
|
||||
if (!(selector instanceof jQuery)) {
|
||||
selector = $(selector)
|
||||
}
|
||||
selector.each(function (i, o) {
|
||||
if ($(this).is(':visible')) {
|
||||
$(this).justifiedGallery({
|
||||
rowHeight: 220,
|
||||
margins: 4
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
diffDate: (d, more = false) => {
|
||||
const dateNow = new Date()
|
||||
const datePost = new Date(d)
|
||||
@@ -135,15 +121,11 @@ const btf = {
|
||||
}
|
||||
},
|
||||
|
||||
scrollToDest: (pos, time) => {
|
||||
if (pos < 0 || time < 0) {
|
||||
return
|
||||
}
|
||||
|
||||
const currentPos = window.scrollY || window.screenTop
|
||||
scrollToDest: (pos, time = 500) => {
|
||||
const currentPos = window.pageYOffset
|
||||
if (currentPos > pos) pos = pos - 70
|
||||
|
||||
if ('CSS' in window && CSS.supports('scroll-behavior', 'smooth')) {
|
||||
if ('scrollBehavior' in document.documentElement.style) {
|
||||
window.scrollTo({
|
||||
top: pos,
|
||||
behavior: 'smooth'
|
||||
@@ -152,25 +134,19 @@ const btf = {
|
||||
}
|
||||
|
||||
let start = null
|
||||
time = time || 500
|
||||
pos = +pos
|
||||
window.requestAnimationFrame(function step (currentTime) {
|
||||
start = !start ? currentTime : start
|
||||
const progress = currentTime - start
|
||||
if (currentPos < pos) {
|
||||
const progress = currentTime - start
|
||||
window.scrollTo(0, ((pos - currentPos) * progress / time) + currentPos)
|
||||
if (progress < time) {
|
||||
window.requestAnimationFrame(step)
|
||||
} else {
|
||||
window.scrollTo(0, pos)
|
||||
}
|
||||
} else {
|
||||
const progress = currentTime - start
|
||||
window.scrollTo(0, currentPos - ((currentPos - pos) * progress / time))
|
||||
if (progress < time) {
|
||||
window.requestAnimationFrame(step)
|
||||
} else {
|
||||
window.scrollTo(0, pos)
|
||||
}
|
||||
}
|
||||
if (progress < time) {
|
||||
window.requestAnimationFrame(step)
|
||||
} else {
|
||||
window.scrollTo(0, pos)
|
||||
}
|
||||
})
|
||||
},
|
||||
@@ -226,14 +202,6 @@ const btf = {
|
||||
}
|
||||
},
|
||||
|
||||
isJqueryLoad: fn => {
|
||||
if (typeof jQuery === 'undefined') {
|
||||
getScript(GLOBAL_CONFIG.source.jQuery).then(fn)
|
||||
} else {
|
||||
fn()
|
||||
}
|
||||
},
|
||||
|
||||
isHidden: ele => ele.offsetHeight === 0 && ele.offsetWidth === 0,
|
||||
|
||||
getEleTop: ele => {
|
||||
@@ -265,14 +233,35 @@ const btf = {
|
||||
ele.forEach(i => {
|
||||
if (i.parentNode.tagName !== 'A') {
|
||||
const dataSrc = i.dataset.lazySrc || i.src
|
||||
const dataCaption = i.alt || ''
|
||||
const dataCaption = i.title || i.alt || ''
|
||||
btf.wrap(i, 'a', { href: dataSrc, 'data-fancybox': 'gallery', 'data-caption': dataCaption, 'data-thumb': dataSrc })
|
||||
}
|
||||
})
|
||||
|
||||
Fancybox.bind('[data-fancybox]', {
|
||||
Hash: false
|
||||
})
|
||||
if (!window.fancyboxRun) {
|
||||
Fancybox.bind('[data-fancybox]', {
|
||||
Hash: false,
|
||||
Thumbs: {
|
||||
autoStart: false
|
||||
}
|
||||
})
|
||||
window.fancyboxRun = true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
initJustifiedGallery: function (selector) {
|
||||
selector.forEach(function (i) {
|
||||
if (!btf.isHidden(i)) {
|
||||
fjGallery(i, {
|
||||
itemSelector: '.fj-gallery-item',
|
||||
rowHeight: 220,
|
||||
gutter: 4,
|
||||
onJustify: function () {
|
||||
this.$container.style.opacity = '1'
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user