mirror of
https://github.com/jerryc127/hexo-theme-butterfly.git
synced 2026-04-08 12:07:06 +08:00
feat: 去除 jQuery (fancybox和圖庫 仍需要加載jQuery)
feat: 點擊文字特效增加隨機配置 feat: 可配置是否添加css前綴 fix: 修復子目錄下,配置justifiedGallery CDN(相對鏈接)後,連接會無法訪問的bugs fix: 修復 pangu 配置post 後,仍在全站生效的bugs improvement: 夜間模式下,廣告降低亮度 improvement: 手機端toc邊距微調 improvement: html格式優化 improvement: 搜索優化 improvement: 刪除不必要的語言文件
This commit is contained in:
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -26,7 +26,7 @@ If you are a problem when visiting the website, please open your browser 'develo
|
||||
<!-- Check all with "x" especially FAQ & Documentation!! (使用 "x" 選擇) -->
|
||||
<!-- 請確認是否都已經翻閲過如下的資料, 尤其是安裝文件!! -->
|
||||
- [] Yes, I have read [Hexo Docs page](https://hexo.io/docs/), especially [Templates](https://hexo.io/docs/templates.html), [Variables](https://hexo.io/docs/variables.html), [Helpers](https://hexo.io/docs/helpers.html) and [Troubleshooting](https://hexo.io/docs/troubleshooting.html).
|
||||
- [] Yes, I have read [Butterfly Documentation](https://demo.jerryc.me/posts/21cfbf15/).
|
||||
- [] Yes, I have read [Butterfly Documentation](https://butterfly.js.org/posts/21cfbf15/).
|
||||
- [] And yes, I already searched for current [issues](https://github.com/jerryc127/hexo-theme-butterfly/issues?utf8=%E2%9C%93&q=is%3Aissue) and this did not help me.
|
||||
|
||||
## Butterfly Information
|
||||
|
||||
@@ -71,7 +71,7 @@ npm i hexo-theme-butterfly
|
||||
- [x] Related articles
|
||||
- [x] Displays outdated notice for a post
|
||||
- [x] Share (AddThis/Sharejs/Addtoany)
|
||||
- [X] Comment (Disqus/Disqusjs/Livere/Gitalk/Valine/Utterances/Facebook Comments)
|
||||
- [X] Comment (Disqus/Disqusjs/Livere/Gitalk/Valine/Utterances/Facebook Comments/Twikoo)
|
||||
- [x] Multiple Comment System Support
|
||||
- [x] Online Chats (Chatra/Tidio/Daovoice/Gitter/Crisp)
|
||||
- [x] Web analytics (Baidu Analytics/Google Analytics/Tencent Analytics/CNZZ Analytics)
|
||||
|
||||
@@ -71,7 +71,7 @@ theme: butterfly
|
||||
- [x] 顯示相關文章
|
||||
- [x] 過期文章提醒
|
||||
- [x] 多種分享系統(AddThis/Sharejs/Addtoany)
|
||||
- [X] 多種評論系統(Disqus/Disqusjs/Livere/Gitalk/Valine/Utterances/Facebook Comments)
|
||||
- [X] 多種評論系統(Disqus/Disqusjs/Livere/Gitalk/Valine/Utterances/Facebook Comments/Twikoo)
|
||||
- [x] 支持雙評論部署
|
||||
- [x] 多種在線聊天(Chatra/Tidio/Daovoice/Gitter/Crisp)
|
||||
- [x] 多種分析系統(百度分析/谷歌分析/騰訊分析/CNZZ分析)
|
||||
|
||||
@@ -542,6 +542,7 @@ ClickShowText:
|
||||
# - LOVE
|
||||
# - YOU
|
||||
fontSize: 15px
|
||||
random: false
|
||||
mobile: false
|
||||
|
||||
# Default display mode (網站默認的顯示模式)
|
||||
@@ -814,6 +815,9 @@ Open_Graph_meta: true
|
||||
# Caches the contents in a fragment, speed up the generation (開啟hexo自帶的緩存,加快生成速度)
|
||||
fragment_cache: true
|
||||
|
||||
# Add the vendor prefixes to ensure compatibility
|
||||
css_prefix: true
|
||||
|
||||
# Inject
|
||||
# Insert the code to head (before '</head>' tag) and the bottom (before '</body>' tag)
|
||||
# 插入代码到头部 </head> 之前 和 底部 </body> 之前
|
||||
|
||||
@@ -41,7 +41,6 @@ local_search:
|
||||
label: Local search
|
||||
input_placeholder: Search for Posts
|
||||
hits_empty: "We didn't find any results for the search: ${query}"
|
||||
powered_by: Powered by
|
||||
|
||||
pagination:
|
||||
prev: Previous Post
|
||||
|
||||
@@ -41,7 +41,6 @@ local_search:
|
||||
label: Local search
|
||||
input_placeholder: Search for Posts
|
||||
hits_empty: "We didn't find any results for the search: ${query}"
|
||||
powered_by: Powered by
|
||||
|
||||
pagination:
|
||||
prev: Previous Post
|
||||
|
||||
@@ -42,8 +42,6 @@ local_search:
|
||||
label: 本地搜索
|
||||
input_placeholder: 搜索文章
|
||||
hits_empty: '找不到您查询的内容:${query}'
|
||||
powered: '提供支持'
|
||||
by: 由
|
||||
|
||||
pagination:
|
||||
prev: 上一篇
|
||||
|
||||
@@ -42,8 +42,6 @@ local_search:
|
||||
label: 本地搜尋
|
||||
input_placeholder: 搜尋文章
|
||||
hits_empty: '找不到您查詢的內容:${query}'
|
||||
powered: '提供支援'
|
||||
by: 由
|
||||
|
||||
pagination:
|
||||
prev: 上一篇
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
div
|
||||
script(src=url_for(theme.CDN.jquery))
|
||||
script(src=url_for(theme.CDN.utils))
|
||||
script(src=url_for(theme.CDN.main))
|
||||
|
||||
@@ -8,11 +7,9 @@ div
|
||||
|
||||
if theme.medium_zoom
|
||||
script(src=url_for(theme.CDN.medium_zoom))
|
||||
else if theme.fancybox
|
||||
script(src=url_for(theme.CDN.fancybox))
|
||||
|
||||
if theme.instantpage
|
||||
script(src=url_for(theme.CDN.instantpage) type="module" defer)
|
||||
script(src=url_for(theme.CDN.instantpage) type="module")
|
||||
|
||||
if theme.lazyload.enable
|
||||
script(src=url_for(theme.CDN.lazyload))
|
||||
@@ -35,9 +32,6 @@ div
|
||||
.js-pjax
|
||||
if theme.subtitle.enable && is_home() && theme.index_img !== false
|
||||
include ./third-party/subtitle.pug
|
||||
|
||||
if page.type === 'artitalk'
|
||||
include ./third-party/artitalk.pug
|
||||
|
||||
include ./third-party/math/index.pug
|
||||
|
||||
|
||||
@@ -53,9 +53,6 @@ if (theme.pwa && theme.pwa.enable)
|
||||
link(rel='stylesheet', href=url_for(theme.CDN.main_css))
|
||||
link(rel='stylesheet', href=url_for(theme.CDN.fontawesome))
|
||||
|
||||
if theme.fancybox
|
||||
link(rel='stylesheet', href=url_for(theme.CDN.fancybox_css))
|
||||
|
||||
if (theme.snackbar && theme.snackbar.enable)
|
||||
link(rel='stylesheet', href=url_for(theme.CDN.snackbar_css))
|
||||
|
||||
|
||||
@@ -54,7 +54,8 @@
|
||||
if (theme.ClickShowText && theme.ClickShowText.enable) {
|
||||
ClickShowText = JSON.stringify({
|
||||
text: theme.ClickShowText.text.join(","),
|
||||
fontSize: theme.ClickShowText.fontSize
|
||||
fontSize: theme.ClickShowText.fontSize,
|
||||
random: theme.ClickShowText.random
|
||||
})
|
||||
}
|
||||
|
||||
@@ -119,9 +120,16 @@ script.
|
||||
ClickShowText: !{ClickShowText},
|
||||
lightbox: '!{ theme.medium_zoom ? "mediumZoom" : (theme.fancybox ? "fancybox" : "null" )}',
|
||||
Snackbar: !{Snackbar},
|
||||
justifiedGallery: {
|
||||
js: '!{theme.CDN.justifiedGallery_js}',
|
||||
css: '!{theme.CDN.justifiedGallery_css}'
|
||||
source: {
|
||||
jQuery: '!{url_for(theme.CDN.jquery)}',
|
||||
justifiedGallery: {
|
||||
js: '!{url_for(theme.CDN.justifiedGallery_js)}',
|
||||
css: '!{url_for(theme.CDN.justifiedGallery_css)}'
|
||||
},
|
||||
fancybox: {
|
||||
js: '!{url_for(theme.CDN.fancybox)}',
|
||||
css: '!{url_for(theme.CDN.fancybox_css)}'
|
||||
}
|
||||
},
|
||||
isPhotoFigcaption: !{theme.photofigcaption},
|
||||
islazyload: !{theme.lazyload.enable},
|
||||
@@ -156,5 +164,17 @@ script.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// https://stackoverflow.com/questions/16839698/jquery-getscript-alternative-in-native-javascript
|
||||
const getScript = url => new Promise((resolve, reject) => {
|
||||
const script = document.createElement('script')
|
||||
script.src = url
|
||||
script.async = true
|
||||
script.onerror = reject
|
||||
script.onload = script.onreadystatechange = function() {
|
||||
const loadState = this.readyState
|
||||
if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
|
||||
script.onload = script.onreadystatechange = null
|
||||
resolve()
|
||||
}
|
||||
document.head.appendChild(script)
|
||||
})
|
||||
@@ -1,7 +1,7 @@
|
||||
link(rel="preconnect" href="//cdn.jsdelivr.net")
|
||||
|
||||
if theme.google_analytics
|
||||
link(rel="preconnect" href="//www.google-analytics.com" crossorigin)
|
||||
link(rel="preconnect" href="//www.google-analytics.com" crossorigin='')
|
||||
|
||||
if theme.baidu_analytics
|
||||
link(rel="preconnect" href="//hm.baidu.com")
|
||||
@@ -13,7 +13,7 @@ if theme.cnzz_analytics
|
||||
link(rel="preconnect" href="//s4.cnzz.com")
|
||||
|
||||
if theme.blog_title_font && theme.blog_title_font.font_link && theme.blog_title_font.font_link.indexOf('//fonts.googleapis.com') != -1
|
||||
link(rel="preconnect" href="//fonts.googleapis.com" crossorigin)
|
||||
link(rel="preconnect" href="//fonts.googleapis.com" crossorigin='')
|
||||
|
||||
if theme.busuanzi.site_uv || theme.busuanzi.site_pv || theme.busuanzi.page_pv
|
||||
link(rel="preconnect" href="//busuanzi.ibruce.info")
|
||||
|
||||
@@ -2,15 +2,15 @@ nav#nav
|
||||
span#blog_name
|
||||
a#site-name(href=url_for('/')) #[=config.title]
|
||||
|
||||
span#menus
|
||||
#menus
|
||||
if (theme.algolia_search.enable || theme.local_search.enable)
|
||||
#search_button
|
||||
#search-button
|
||||
a.site-page.social-icon.search
|
||||
i.fas.fa-search.fa-fw
|
||||
span=' '+_p('search')
|
||||
!=fragment_cache('menus', function(){return partial('includes/header/menu_item')})
|
||||
|
||||
span#toggle-menu.close
|
||||
#toggle-menu
|
||||
a.site-page
|
||||
i.fas.fa-bars.fa-fw
|
||||
|
||||
|
||||
@@ -78,4 +78,4 @@ mixin postUI(posts)
|
||||
|
||||
if theme.ad && theme.ad.index
|
||||
if (index + 1) % 3 == 0
|
||||
.recent-post-item.ad-height!=theme.ad.index
|
||||
.recent-post-item.ads-wrap!=theme.ad.index
|
||||
|
||||
@@ -1,4 +1,28 @@
|
||||
- let option = theme.artitalk.option ? JSON.stringify(theme.artitalk.option) : false
|
||||
|
||||
if top_img === false
|
||||
h1.page-title= page.title
|
||||
|
||||
#artitalk_main
|
||||
#artitalk_main
|
||||
script.
|
||||
(()=>{
|
||||
let setting = {
|
||||
appId: '!{theme.artitalk.appId}',
|
||||
appKey: '!{theme.artitalk.appKey}',
|
||||
}
|
||||
|
||||
if (!{Boolean(option)}) {
|
||||
const otherSetting = !{option}
|
||||
setting = Object.assign({}, setting, otherSetting)
|
||||
}
|
||||
|
||||
const init = () => {
|
||||
new Artitalk(setting)
|
||||
}
|
||||
|
||||
if (typeof Artitalk === 'function') {
|
||||
init()
|
||||
} else {
|
||||
getScript('!{theme.CDN.artitalk}').then(init)
|
||||
}
|
||||
})()
|
||||
@@ -18,9 +18,9 @@ else
|
||||
- var pagination_cover = page.prev.cover === false ? page.prev.randomcover : page.prev.cover
|
||||
a(href=url_for(page.prev.path))
|
||||
if theme.lazyload.enable
|
||||
img.prev-cover(data-lazy-src=url_for(pagination_cover) onerror=`onerror=null;src='${url_for(theme.error_img.post_page)}'` )
|
||||
img.prev-cover(data-lazy-src=url_for(pagination_cover) onerror=`onerror=null;src='${url_for(theme.error_img.post_page)}'` alt='cover of previous post')
|
||||
else
|
||||
img.prev-cover(src=url_for(pagination_cover) onerror=`onerror=null;src='${url_for(theme.error_img.post_page)}'` )
|
||||
img.prev-cover(src=url_for(pagination_cover) onerror=`onerror=null;src='${url_for(theme.error_img.post_page)}'` alt='cover of previous post')
|
||||
.pagination-info
|
||||
.label=_p('pagination.prev')
|
||||
.prev_info=page.prev.title
|
||||
@@ -31,9 +31,9 @@ else
|
||||
.next-post(class=hasPagePrev)
|
||||
a(href=url_for(page.next.path))
|
||||
if theme.lazyload.enable
|
||||
img.next-cover(data-lazy-src=url_for(pagination_cover) onerror=`onerror=null;src='${url_for(theme.error_img.post_page)}'`)
|
||||
img.next-cover(data-lazy-src=url_for(pagination_cover) onerror=`onerror=null;src='${url_for(theme.error_img.post_page)}'` alt='cover of next post')
|
||||
else
|
||||
img.next-cover(src=url_for(pagination_cover) onerror=`onerror=null;src='${url_for(theme.error_img.post_page)}'`)
|
||||
img.next-cover(src=url_for(pagination_cover) onerror=`onerror=null;src='${url_for(theme.error_img.post_page)}'` alt='cover of next post')
|
||||
.pagination-info
|
||||
.label=_p('pagination.next')
|
||||
.next_info=page.next.title
|
||||
24
layout/includes/third-party/artitalk.pug
vendored
24
layout/includes/third-party/artitalk.pug
vendored
@@ -1,24 +0,0 @@
|
||||
- let option = theme.artitalk.option ? JSON.stringify(theme.artitalk.option) : false
|
||||
|
||||
script.
|
||||
(()=>{
|
||||
let setting = {
|
||||
appId: '!{theme.artitalk.appId}',
|
||||
appKey: '!{theme.artitalk.appKey}',
|
||||
}
|
||||
|
||||
if (!{Boolean(option)}) {
|
||||
const otherSetting = !{option}
|
||||
setting = Object.assign({}, setting, otherSetting)
|
||||
}
|
||||
|
||||
const init = () => {
|
||||
new Artitalk(setting)
|
||||
}
|
||||
|
||||
if (typeof Artitalk === 'function') {
|
||||
init()
|
||||
} else {
|
||||
$.getScript('!{theme.CDN.artitalk}',init)
|
||||
}
|
||||
})()
|
||||
6
layout/includes/third-party/baidu_push.pug
vendored
6
layout/includes/third-party/baidu_push.pug
vendored
@@ -3,11 +3,11 @@ if theme.baidu_push
|
||||
(function(){
|
||||
const bp = document.createElement('script');
|
||||
const curProtocol = window.location.protocol.split(':')[0];
|
||||
if (curProtocol === 'https'){
|
||||
bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
|
||||
if (curProtocol === 'https') {
|
||||
bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
|
||||
}
|
||||
else{
|
||||
bp.src = 'http://push.zhanzhang.baidu.com/push.js';
|
||||
bp.src = 'http://push.zhanzhang.baidu.com/push.js';
|
||||
}
|
||||
bp.dataset.pjax = ''
|
||||
const s = document.getElementsByTagName("script")[0];
|
||||
|
||||
@@ -29,7 +29,7 @@ script.
|
||||
if (window.disqusJsLoad) initDisqusjs()
|
||||
else {
|
||||
addDisqusjsCSS()
|
||||
$.getScript('!{url_for(theme.CDN.disqusjs)}', initDisqusjs)
|
||||
getScript('!{url_for(theme.CDN.disqusjs)}').then(initDisqusjs)
|
||||
window.disqusJsLoad = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ script.
|
||||
if (typeof Gitalk === 'function') initGitalk()
|
||||
else {
|
||||
addGitalkSource()
|
||||
$.getScript('!{url_for(theme.CDN.gitalk)}', initGitalk)
|
||||
getScript('!{url_for(theme.CDN.gitalk)}').then(initGitalk)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ script.
|
||||
if (typeof twikoo.init === 'function') {
|
||||
init()
|
||||
} else {
|
||||
$.getScript('!{theme.CDN.twikoo}', init)
|
||||
getScript('!{theme.CDN.twikoo}').then(init)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ script.
|
||||
}
|
||||
|
||||
if (typeof Valine === 'function') initValine()
|
||||
else $.getScript('!{url_for(theme.CDN.valine)}', initValine)
|
||||
else getScript('!{url_for(theme.CDN.valine)}').then(initValine)
|
||||
}
|
||||
|
||||
if ('!{theme.comments.use[0]}' === 'Valine' || !!{theme.comments.lazyload}) {
|
||||
|
||||
9
layout/includes/third-party/math/katex.pug
vendored
9
layout/includes/third-party/math/katex.pug
vendored
@@ -2,6 +2,9 @@ link(rel="stylesheet" type="text/css" href=theme.CDN.katex)
|
||||
script(src=url_for(theme.CDN.katex_copytex))
|
||||
link(rel="stylesheet" type="text/css" href=theme.CDN.katex_copytex_css)
|
||||
script.
|
||||
$(function () {
|
||||
$('span.katex-display').wrap('<div class="katex-wrap"></div>')
|
||||
})
|
||||
(() => {
|
||||
document.querySelectorAll('#article-container span.katex-display').forEach(item => {
|
||||
btf.wrap(item, 'div', '', 'katex-wrap')
|
||||
})
|
||||
})()
|
||||
|
||||
2
layout/includes/third-party/math/mermaid.pug
vendored
2
layout/includes/third-party/math/mermaid.pug
vendored
@@ -2,7 +2,7 @@ script.
|
||||
if (document.getElementsByClassName('mermaid').length) {
|
||||
if (window.mermaidJsLoad) mermaid.init()
|
||||
else {
|
||||
$.getScript('!{theme.CDN.mermaid}', function () {
|
||||
getScript('!{theme.CDN.mermaid}').then(() => {
|
||||
window.mermaidJsLoad = true
|
||||
mermaid.initialize({
|
||||
theme: '!{theme.mermaid.theme}',
|
||||
|
||||
@@ -14,24 +14,25 @@ script.
|
||||
}
|
||||
|
||||
const getDisqusComment = () => {
|
||||
let disqusArray = []
|
||||
$.getJSON('https://disqus.com/api/3.0/forums/listPosts.json?forum=!{theme.newest_comments.disqus.forum}&related=thread&limit=!{theme.newest_comments.limit}&api_key=!{theme.newest_comments.disqus.api_key}', function(data){
|
||||
$.each(data.response, (i, item) => {
|
||||
disqusArray.push({
|
||||
'avatar': item.author.avatar.cache,
|
||||
'content': changeContent(item.message),
|
||||
'nick': item.author.name,
|
||||
'url': item.url,
|
||||
'date': item.createdAt
|
||||
fetch('https://disqus.com/api/3.0/forums/listPosts.json?forum=!{theme.newest_comments.disqus.forum}&related=thread&limit=!{theme.newest_comments.limit}&api_key=!{theme.newest_comments.disqus.api_key}')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
const disqusArray = data.response.map(item => {
|
||||
return {
|
||||
'avatar': item.author.avatar.cache,
|
||||
'content': changeContent(item.message),
|
||||
'nick': item.author.name,
|
||||
'url': item.url,
|
||||
'date': item.createdAt
|
||||
}
|
||||
})
|
||||
// set expiry to 10 min
|
||||
saveToLocal.set('disqus-newest-comments', JSON.stringify(disqusArray), 10/(60*24))
|
||||
generateHtml(disqusArray)
|
||||
}).catch(e => {
|
||||
const $dom = document.querySelector('#card-newest-comments .aside-list')
|
||||
$dom.innerHTML= "!{_p('aside.card_newest_comments.error')}"
|
||||
})
|
||||
// set expiry to 10 min
|
||||
saveToLocal.set('disqus-newest-comments', JSON.stringify(disqusArray), 10/(60*24))
|
||||
generateHtml(disqusArray)
|
||||
}).fail(()=>{
|
||||
const $dom = document.querySelector('#card-newest-comments .aside-list')
|
||||
$dom.innerHTML= "!{_p('aside.card_newest_comments.error')}"
|
||||
})
|
||||
}
|
||||
|
||||
const generateHtml = array => {
|
||||
|
||||
@@ -14,23 +14,24 @@ script.
|
||||
}
|
||||
|
||||
const getGithubIssues = () => {
|
||||
let githubArray = []
|
||||
$.getJSON('https://api.github.com/repos/!{theme.newest_comments.github_issues.repo}/issues/comments?sort=updated&direction=desc&per_page=!{theme.newest_comments.limit}&page=1', (data) => {
|
||||
$.each(data, (index, item) => {
|
||||
githubArray.push({
|
||||
'avatar': item.user.avatar_url,
|
||||
'content': changeContent(item.body),
|
||||
'nick': item.user.login,
|
||||
'url': item.html_url,
|
||||
'date': item.updated_at
|
||||
fetch('https://api.github.com/repos/!{theme.newest_comments.github_issues.repo}/issues/comments?sort=updated&direction=desc&per_page=!{theme.newest_comments.limit}&page=1')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
const githubArray = data.map(item => {
|
||||
return {
|
||||
'avatar': item.user.avatar_url,
|
||||
'content': changeContent(item.body),
|
||||
'nick': item.user.login,
|
||||
'url': item.html_url,
|
||||
'date': item.updated_at
|
||||
}
|
||||
})
|
||||
saveToLocal.set('github-newest-comments', JSON.stringify(githubArray), 10/(60*24))
|
||||
generateHtml(githubArray)
|
||||
}).catch(e => {
|
||||
const $dom = document.querySelector('#card-newest-comments .aside-list')
|
||||
$dom.innerHTML= "!{_p('aside.card_newest_comments.error')}"
|
||||
})
|
||||
saveToLocal.set('github-newest-comments', JSON.stringify(githubArray), 10/(60*24))
|
||||
generateHtml(githubArray)
|
||||
}).fail(()=>{
|
||||
const $dom = document.querySelector('#card-newest-comments .aside-list')
|
||||
$dom.innerHTML= "!{_p('aside.card_newest_comments.error')}"
|
||||
})
|
||||
}
|
||||
|
||||
const generateHtml = array => {
|
||||
|
||||
@@ -51,9 +51,7 @@ script.
|
||||
}
|
||||
|
||||
var settings = {
|
||||
"url": `${serverURL}/1.1/classes/Comment?limit=!{theme.newest_comments.limit}&order=-createdAt`,
|
||||
"method": "GET",
|
||||
"timeout": 0,
|
||||
"headers": {
|
||||
"X-LC-Id": '!{theme.newest_comments.leancloud.appId}',
|
||||
"X-LC-Key": '!{theme.newest_comments.leancloud.appKey}',
|
||||
@@ -61,26 +59,25 @@ script.
|
||||
},
|
||||
}
|
||||
|
||||
$.ajax(settings).done((response) => {
|
||||
var valineArray = []
|
||||
response.results.forEach((e)=>{
|
||||
valineArray.push({
|
||||
'avatar': e.QQAvatar,
|
||||
'content': changeContent(e.comment),
|
||||
'mail': e.mail,
|
||||
'nick': e.nick,
|
||||
'url': e.url,
|
||||
'date': e.createdAt,
|
||||
fetch(`${serverURL}/1.1/classes/Comment?limit=!{theme.newest_comments.limit}&order=-createdAt`,settings)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
const valineArray = data.results.map(function (e) {
|
||||
return {
|
||||
'avatar': e.QQAvatar,
|
||||
'content': changeContent(e.comment),
|
||||
'mail': e.mail,
|
||||
'nick': e.nick,
|
||||
'url': e.url,
|
||||
'date': e.createdAt,
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
saveToLocal.set('leancloud-newest-comments', JSON.stringify(valineArray), 10/(60*24))
|
||||
generateHtml(valineArray)
|
||||
|
||||
}).fail(()=>{
|
||||
const $dom = document.querySelector('#card-newest-comments .aside-list')
|
||||
$dom.innerHTML= "!{_p('aside.card_newest_comments.error')}"
|
||||
})
|
||||
saveToLocal.set('leancloud-newest-comments', JSON.stringify(valineArray), 10/(60*24))
|
||||
generateHtml(valineArray)
|
||||
}).catch(e => {
|
||||
const $dom = document.querySelector('#card-newest-comments .aside-list')
|
||||
$dom.innerHTML= "!{_p('aside.card_newest_comments.error')}"
|
||||
})
|
||||
}
|
||||
|
||||
const newestCommentInit = () => {
|
||||
|
||||
9
layout/includes/third-party/pangu.pug
vendored
9
layout/includes/third-party/pangu.pug
vendored
@@ -2,9 +2,10 @@ script.
|
||||
function panguFn () {
|
||||
if (typeof pangu === 'object') pangu.spacingElementById('content-inner')
|
||||
else {
|
||||
$.getScript('!{url_for(theme.CDN.pangu)}', () => {
|
||||
pangu.spacingElementById('content-inner')
|
||||
})
|
||||
getScript('!{url_for(theme.CDN.pangu)}')
|
||||
.then(() => {
|
||||
pangu.spacingElementById('content-inner')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,4 +17,4 @@ script.
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', panguFn)
|
||||
document.addEventListener('DOMContentLoaded', panguInit)
|
||||
|
||||
14
layout/includes/third-party/pjax.pug
vendored
14
layout/includes/third-party/pjax.pug
vendored
@@ -29,8 +29,12 @@ script.
|
||||
document.addEventListener('pjax:complete', function () {
|
||||
window.refreshFn()
|
||||
|
||||
$('script[data-pjax]').each(function () {
|
||||
$(this).parent().append($(this).remove())
|
||||
document.querySelectorAll('script[data-pjax]').forEach(item => {
|
||||
const newScript = document.createElement('script')
|
||||
const content = item.text || item.textContent || item.innerHTML || ""
|
||||
Array.from(item.attributes).forEach(attr => newScript.setAttribute(attr.name, attr.value))
|
||||
newScript.appendChild(document.createTextNode(content))
|
||||
item.parentNode.replaceChild(newScript, item)
|
||||
})
|
||||
|
||||
GLOBAL_CONFIG.islazyload && window.lazyLoadInstance.update()
|
||||
@@ -69,10 +73,8 @@ script.
|
||||
|
||||
typeof typed === 'object' && typed.destroy()
|
||||
|
||||
$(window).off('scroll')
|
||||
|
||||
//reset readmode
|
||||
$('body').hasClass('read-mode') && $('body').removeClass('read-mode')
|
||||
const $bodyClassList = document.body.classList
|
||||
$bodyClassList.contains('read-mode') && $bodyClassList.remove('read-mode')
|
||||
|
||||
})
|
||||
|
||||
|
||||
@@ -7,18 +7,6 @@
|
||||
input(placeholder=_p("local_search.input_placeholder") type="text").local-search-box--input
|
||||
hr
|
||||
#local-search-results
|
||||
#local-hits
|
||||
#local-stats
|
||||
#hr.local-search-stats__hr
|
||||
case config.language
|
||||
when "zh-CN"
|
||||
span=_p("local_search.by")
|
||||
| #[a(href="https://github.com/wzpan/hexo-generator-search" style={'color': '#49B1F5'}) hexo-generator-search]
|
||||
| #[span=_p("local_search.powered")]
|
||||
when "en"
|
||||
default
|
||||
span=_p("local_search.powered_by")
|
||||
| #[a(href="https://github.com/wzpan/hexo-generator-search" style={'color': '#49B1F5'}) hexo-generator-search]
|
||||
span.search-close-button
|
||||
i.fas.fa-times
|
||||
#search-mask
|
||||
110
layout/includes/third-party/subtitle.pug
vendored
110
layout/includes/third-party/subtitle.pug
vendored
@@ -1,28 +1,34 @@
|
||||
- var source = theme.subtitle.source
|
||||
- let source = theme.subtitle.source
|
||||
|
||||
case source
|
||||
when 1
|
||||
script.
|
||||
function subtitleType () {
|
||||
$.getJSON('https://api.btstu.cn/yan/api.php?charset=utf-8&encode=json',function (data) {
|
||||
if (!{theme.subtitle.effect}) {
|
||||
var sub = "!{theme.subtitle.sub}".length == 0 ? new Array() : "!{theme.subtitle.sub}".split(',')
|
||||
var both = sub.unshift(data.text)
|
||||
typed = new Typed('#subtitle', {
|
||||
strings: sub,
|
||||
startDelay: 300,
|
||||
typeSpeed: 150,
|
||||
loop: !{theme.subtitle.loop},
|
||||
backSpeed: 50,
|
||||
})
|
||||
} else {
|
||||
document.getElementById('subtitle').innerHTML = data.text
|
||||
}
|
||||
})
|
||||
fetch('https://api.btstu.cn/yan/api.php?charset=utf-8&encode=json')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (!{theme.subtitle.effect}) {
|
||||
var sub = "!{theme.subtitle.sub}".length == 0 ? new Array() : "!{theme.subtitle.sub}".split(',')
|
||||
var both = sub.unshift(data.text)
|
||||
typed = new Typed('#subtitle', {
|
||||
strings: sub,
|
||||
startDelay: 300,
|
||||
typeSpeed: 150,
|
||||
loop: !{theme.subtitle.loop},
|
||||
backSpeed: 50,
|
||||
})
|
||||
} else {
|
||||
document.getElementById('subtitle').innerHTML = data.text
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (!{theme.subtitle.effect}) {
|
||||
if (typeof Typed === 'function') subtitleType()
|
||||
else $.getScript('!{url_for(theme.CDN.typed)}', subtitleType)
|
||||
if (typeof Typed === 'function') {
|
||||
subtitleType()
|
||||
} else {
|
||||
getScript('!{url_for(theme.CDN.typed)}').then(subtitleType)
|
||||
}
|
||||
} else {
|
||||
subtitleType()
|
||||
}
|
||||
@@ -30,27 +36,32 @@ case source
|
||||
when 2
|
||||
script.
|
||||
function subtitleType () {
|
||||
$.getJSON('https://v1.hitokoto.cn', function (data) {
|
||||
if (!{theme.subtitle.effect}) {
|
||||
var from = '出自 ' + data.from
|
||||
var sub = "!{theme.subtitle.sub}".length == 0 ? new Array() : "!{theme.subtitle.sub}".split(',')
|
||||
var both = sub.unshift(data.hitokoto, from)
|
||||
var typed = new Typed('#subtitle', {
|
||||
strings: sub,
|
||||
startDelay: 300,
|
||||
typeSpeed: 150,
|
||||
loop: !{theme.subtitle.loop},
|
||||
backSpeed: 50,
|
||||
})
|
||||
} else {
|
||||
document.getElementById('subtitle').innerHTML = data.hitokoto
|
||||
}
|
||||
})
|
||||
fetch('https://v1.hitokoto.cn')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (!{theme.subtitle.effect}) {
|
||||
var from = '出自 ' + data.from
|
||||
var sub = "!{theme.subtitle.sub}".length == 0 ? new Array() : "!{theme.subtitle.sub}".split(',')
|
||||
var both = sub.unshift(data.hitokoto, from)
|
||||
var typed = new Typed('#subtitle', {
|
||||
strings: sub,
|
||||
startDelay: 300,
|
||||
typeSpeed: 150,
|
||||
loop: !{theme.subtitle.loop},
|
||||
backSpeed: 50,
|
||||
})
|
||||
} else {
|
||||
document.getElementById('subtitle').innerHTML = data.hitokoto
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (!{theme.subtitle.effect}) {
|
||||
if (typeof Typed === 'function') subtitleType()
|
||||
else $.getScript('!{url_for(theme.CDN.typed)}', subtitleType)
|
||||
if (typeof Typed === 'function') {
|
||||
subtitleType()
|
||||
} else {
|
||||
getScript('!{url_for(theme.CDN.typed)}').then(subtitleType)
|
||||
}
|
||||
} else {
|
||||
subtitleType()
|
||||
}
|
||||
@@ -58,7 +69,7 @@ case source
|
||||
when 3
|
||||
script.
|
||||
function subtitleType () {
|
||||
$.getScript('http://yijuzhan.com/api/word.php?m=js', function () {
|
||||
getScript('http://yijuzhan.com/api/word.php?m=js').then(() => {
|
||||
var con = str[0]
|
||||
if (!{theme.subtitle.effect}) {
|
||||
var from = '出自 ' + str[1]
|
||||
@@ -78,8 +89,11 @@ case source
|
||||
}
|
||||
|
||||
if (!{theme.subtitle.effect}) {
|
||||
if (typeof Typed === 'function') subtitleType()
|
||||
else $.getScript('!{url_for(theme.CDN.typed)}', subtitleType)
|
||||
if (typeof Typed === 'function') {
|
||||
subtitleType()
|
||||
} else {
|
||||
getScript('!{url_for(theme.CDN.typed)}').then(subtitleType)
|
||||
}
|
||||
} else {
|
||||
subtitleType()
|
||||
}
|
||||
@@ -87,7 +101,7 @@ case source
|
||||
when 4
|
||||
script.
|
||||
function subtitleType () {
|
||||
$.getScript('https://sdk.jinrishici.com/v2/browser/jinrishici.js',function () {
|
||||
getScript('https://sdk.jinrishici.com/v2/browser/jinrishici.js').then(() => {
|
||||
jinrishici.load(function (result) {
|
||||
if (!{theme.subtitle.effect}) {
|
||||
var sub = "!{theme.subtitle.sub}".length == 0 ? new Array() : "!{theme.subtitle.sub}".split(',')
|
||||
@@ -108,8 +122,11 @@ case source
|
||||
}
|
||||
|
||||
if (!{theme.subtitle.effect}) {
|
||||
if (typeof Typed === 'function') subtitleType()
|
||||
else $.getScript('!{url_for(theme.CDN.typed)}', subtitleType)
|
||||
if (typeof Typed === 'function') {
|
||||
subtitleType()
|
||||
} else {
|
||||
getScript('!{url_for(theme.CDN.typed)}').then(subtitleType)
|
||||
}
|
||||
} else {
|
||||
subtitleType()
|
||||
}
|
||||
@@ -131,8 +148,11 @@ case source
|
||||
}
|
||||
|
||||
if (!{theme.subtitle.effect}) {
|
||||
if (typeof Typed === 'function') subtitleType()
|
||||
else $.getScript('!{url_for(theme.CDN.typed)}', subtitleType)
|
||||
if (typeof Typed === 'function') {
|
||||
subtitleType()
|
||||
} else {
|
||||
getScript('!{url_for(theme.CDN.typed)}').then(subtitleType)
|
||||
}
|
||||
} else {
|
||||
subtitleType()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
.card-widget.card-ad
|
||||
!= theme.ad.aside
|
||||
if theme.ad && theme.ad.aside
|
||||
.card-widget.ads-wrap
|
||||
!= theme.ad.aside
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
.card-widget.card-announcement
|
||||
.card-content
|
||||
.item-headline
|
||||
i.fas.fa-bullhorn.card-announcement-animation
|
||||
span= _p('aside.card_announcement')
|
||||
.announcement_content!= theme.aside.card_announcement.content
|
||||
if theme.aside.card_announcement.enable
|
||||
.card-widget.card-announcement
|
||||
.card-content
|
||||
.item-headline
|
||||
i.fas.fa-bullhorn.card-announcement-animation
|
||||
span= _p('aside.card_announcement')
|
||||
.announcement_content!= theme.aside.card_announcement.content
|
||||
@@ -1,11 +1,12 @@
|
||||
.card-widget.card-archives
|
||||
.card-content
|
||||
.item-headline
|
||||
i.fas.fa-archive
|
||||
span= _p('aside.card_archives')
|
||||
|
||||
- let type = theme.aside.card_archives.type || 'monthly'
|
||||
- let format = theme.aside.card_archives.format || 'MMMM YYYY'
|
||||
- let order = theme.aside.card_archives.order || -1
|
||||
- let limit = theme.aside.card_archives.limit === 0 ? 0 : theme.aside.card_archives.limit || 8
|
||||
!= aside_archives({ type:type, format: format, order: order, limit: limit })
|
||||
if theme.aside.card_archives.enable
|
||||
.card-widget.card-archives
|
||||
.card-content
|
||||
.item-headline
|
||||
i.fas.fa-archive
|
||||
span= _p('aside.card_archives')
|
||||
|
||||
- let type = theme.aside.card_archives.type || 'monthly'
|
||||
- let format = theme.aside.card_archives.format || 'MMMM YYYY'
|
||||
- let order = theme.aside.card_archives.order || -1
|
||||
- let limit = theme.aside.card_archives.limit === 0 ? 0 : theme.aside.card_archives.limit || 8
|
||||
!= aside_archives({ type:type, format: format, order: order, limit: limit })
|
||||
|
||||
@@ -1,36 +1,37 @@
|
||||
.card-widget.card-info
|
||||
.card-content
|
||||
.card-info-avatar.is-center
|
||||
if theme.lazyload.enable
|
||||
img.avatar-img(data-lazy-src=url_for(theme.avatar.img) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt="avatar")
|
||||
else
|
||||
img.avatar-img(src=url_for(theme.avatar.img) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt="avatar")
|
||||
.author-info__name= config.author
|
||||
.author-info__description!= theme.aside.card_author.description || config.description
|
||||
if theme.aside.card_author.enable
|
||||
.card-widget.card-info
|
||||
.card-content
|
||||
.card-info-avatar.is-center
|
||||
if theme.lazyload.enable
|
||||
img.avatar-img(data-lazy-src=url_for(theme.avatar.img) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt="avatar")
|
||||
else
|
||||
img.avatar-img(src=url_for(theme.avatar.img) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt="avatar")
|
||||
.author-info__name= config.author
|
||||
.author-info__description!= theme.aside.card_author.description || config.description
|
||||
|
||||
.card-info-data
|
||||
if site.posts.length
|
||||
.card-info-data-item.is-center
|
||||
a(href=url_for(config.archive_dir) + '/')
|
||||
.headline= _p('aside.articles')
|
||||
.length-num= site.posts.length
|
||||
.card-info-data
|
||||
if site.posts.length
|
||||
.card-info-data-item.is-center
|
||||
a(href=url_for(config.archive_dir) + '/')
|
||||
.headline= _p('aside.articles')
|
||||
.length-num= site.posts.length
|
||||
|
||||
if site.tags.length
|
||||
.card-info-data-item.is-center
|
||||
a(href=url_for(config.tag_dir) + '/')
|
||||
.headline= _p('aside.tags')
|
||||
.length-num= site.tags.length
|
||||
if site.tags.length
|
||||
.card-info-data-item.is-center
|
||||
a(href=url_for(config.tag_dir) + '/')
|
||||
.headline= _p('aside.tags')
|
||||
.length-num= site.tags.length
|
||||
|
||||
if site.categories.length
|
||||
.card-info-data-item.is-center
|
||||
a(href=url_for(config.category_dir) + '/')
|
||||
.headline= _p('aside.categories')
|
||||
.length-num= site.categories.length
|
||||
if site.categories.length
|
||||
.card-info-data-item.is-center
|
||||
a(href=url_for(config.category_dir) + '/')
|
||||
.headline= _p('aside.categories')
|
||||
.length-num= site.categories.length
|
||||
|
||||
a#card-info-btn.button--animated(href=theme.aside.card_author.button.link)
|
||||
i(class=theme.aside.card_author.button.icon)
|
||||
span=theme.aside.card_author.button.text
|
||||
|
||||
if(theme.social)
|
||||
.card-info-social-icons.is-center
|
||||
!=fragment_cache('social', function(){return partial('includes/header/social')})
|
||||
a#card-info-btn.button--animated(href=theme.aside.card_author.button.link)
|
||||
i(class=theme.aside.card_author.button.icon)
|
||||
span=theme.aside.card_author.button.text
|
||||
|
||||
if(theme.social)
|
||||
.card-info-social-icons.is-center
|
||||
!=fragment_cache('social', function(){return partial('includes/header/social')})
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
if site.categories.length
|
||||
.card-widget.card-categories
|
||||
.card-content
|
||||
.item-headline
|
||||
i.fas.fa-folder-open
|
||||
span= _p('aside.card_categories')
|
||||
!=aside_categories({ limit: theme.aside.card_categories.limit === 0 ? 0 : theme.aside.card_categories.limit || 8 , expand: theme.aside.card_categories.expand })
|
||||
|
||||
|
||||
if theme.aside.card_categories.enable
|
||||
if site.categories.length
|
||||
.card-widget.card-categories
|
||||
.card-content
|
||||
.item-headline
|
||||
i.fas.fa-folder-open
|
||||
span= _p('aside.card_categories')
|
||||
!=aside_categories({ limit: theme.aside.card_categories.limit === 0 ? 0 : theme.aside.card_categories.limit || 8 , expand: theme.aside.card_categories.expand })
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
.card-widget#card-newest-comments
|
||||
.card-content
|
||||
.item-headline
|
||||
i.fas.fa-bolt
|
||||
span= _p('aside.card_newest_comments.headline')
|
||||
.aside-list
|
||||
span= _p('aside.card_newest_comments.loading_text')
|
||||
if theme.newest_comments.enable
|
||||
.card-widget#card-newest-comments
|
||||
.card-content
|
||||
.item-headline
|
||||
i.fas.fa-bolt
|
||||
span= _p('aside.card_newest_comments.headline')
|
||||
.aside-list
|
||||
span= _p('aside.card_newest_comments.loading_text')
|
||||
|
||||
@@ -1,27 +1,28 @@
|
||||
.card-widget.card-recent-post
|
||||
.card-content
|
||||
.item-headline
|
||||
i.fas.fa-history
|
||||
span= _p('aside.card_recent_post')
|
||||
.aside-list
|
||||
- let postLimit = theme.aside.card_recent_post.limit === 0 ? site.posts.length : theme.aside.card_recent_post.limit || 5
|
||||
- let sort = theme.aside.card_recent_post.sort === 'updated' ? 'updated' : 'date'
|
||||
- site.posts.sort(sort, -1).limit(postLimit).each(function(article){
|
||||
- let link = article.link || article.path
|
||||
- let title = article.title || _p('no_title')
|
||||
- let no_cover = article.cover === false || !theme.cover.aside_enable ? 'no-cover' : ''
|
||||
- let post_cover = article.cover
|
||||
.aside-list-item(class=no_cover)
|
||||
if post_cover && theme.cover.aside_enable
|
||||
a.thumbnail(href=url_for(link) title=title)
|
||||
if theme.lazyload.enable
|
||||
img(data-lazy-src=url_for(post_cover) onerror=`this.onerror=null;this.src='${url_for(theme.error_img.post_page)}'` alt=title)
|
||||
if theme.aside.card_recent_post.enable
|
||||
.card-widget.card-recent-post
|
||||
.card-content
|
||||
.item-headline
|
||||
i.fas.fa-history
|
||||
span= _p('aside.card_recent_post')
|
||||
.aside-list
|
||||
- let postLimit = theme.aside.card_recent_post.limit === 0 ? site.posts.length : theme.aside.card_recent_post.limit || 5
|
||||
- let sort = theme.aside.card_recent_post.sort === 'updated' ? 'updated' : 'date'
|
||||
- site.posts.sort(sort, -1).limit(postLimit).each(function(article){
|
||||
- let link = article.link || article.path
|
||||
- let title = article.title || _p('no_title')
|
||||
- let no_cover = article.cover === false || !theme.cover.aside_enable ? 'no-cover' : ''
|
||||
- let post_cover = article.cover
|
||||
.aside-list-item(class=no_cover)
|
||||
if post_cover && theme.cover.aside_enable
|
||||
a.thumbnail(href=url_for(link) title=title)
|
||||
if theme.lazyload.enable
|
||||
img(data-lazy-src=url_for(post_cover) onerror=`this.onerror=null;this.src='${url_for(theme.error_img.post_page)}'` alt=title)
|
||||
else
|
||||
img(src=url_for(post_cover) onerror=`this.onerror=null;this.src='${url_for(theme.error_img.post_page)}'` alt=title)
|
||||
.content
|
||||
a.title(href=url_for(link) title=title)= title
|
||||
if theme.aside.card_recent_post.sort === 'updated'
|
||||
time(datetime=date_xml(article.updated) title=_p('post.updated') + ' ' + full_date(article.updated)) #[=date(article.updated, config.date_format)]
|
||||
else
|
||||
img(src=url_for(post_cover) onerror=`this.onerror=null;this.src='${url_for(theme.error_img.post_page)}'` alt=title)
|
||||
.content
|
||||
a.title(href=url_for(link) title=title)= title
|
||||
if theme.aside.card_recent_post.sort === 'updated'
|
||||
time(datetime=date_xml(article.updated) title=_p('post.updated') + ' ' + full_date(article.updated)) #[=date(article.updated, config.date_format)]
|
||||
else
|
||||
time(datetime=date_xml(article.date) title=_p('post.created') + ' ' + full_date(article.date)) #[=date(article.date, config.date_format)]
|
||||
- })
|
||||
time(datetime=date_xml(article.date) title=_p('post.created') + ' ' + full_date(article.date)) #[=date(article.date, config.date_format)]
|
||||
- })
|
||||
@@ -1,12 +1,13 @@
|
||||
if site.tags.length
|
||||
.card-widget.card-tags
|
||||
.card-content
|
||||
.item-headline
|
||||
i.fas.fa-tags
|
||||
span= _p('aside.card_tags')
|
||||
if theme.aside.card_tags.enable
|
||||
if site.tags.length
|
||||
.card-widget.card-tags
|
||||
.card-content
|
||||
.item-headline
|
||||
i.fas.fa-tags
|
||||
span= _p('aside.card_tags')
|
||||
|
||||
- let tagLimit = theme.aside.card_tags.limit === 0 ? 0 : theme.aside.card_tags.limit || 40
|
||||
if theme.aside.card_tags.color
|
||||
.card-tag-cloud!= cloudTags({source: site.tags, minfontsize: 1.1, maxfontsize: 1.5, limit: tagLimit, unit: 'em'})
|
||||
else
|
||||
.card-tag-cloud!= tagcloud({min_font: 1.1, max_font: 1.5, amount: tagLimit , color: true, start_color: '#999', end_color: '#99a9bf', unit: 'em'})
|
||||
- let tagLimit = theme.aside.card_tags.limit === 0 ? 0 : theme.aside.card_tags.limit || 40
|
||||
if theme.aside.card_tags.color
|
||||
.card-tag-cloud!= cloudTags({source: site.tags, minfontsize: 1.1, maxfontsize: 1.5, limit: tagLimit, unit: 'em'})
|
||||
else
|
||||
.card-tag-cloud!= tagcloud({min_font: 1.1, max_font: 1.5, amount: tagLimit , color: true, start_color: '#999', end_color: '#99a9bf', unit: 'em'})
|
||||
|
||||
@@ -1,31 +1,32 @@
|
||||
.card-widget.card-webinfo
|
||||
.card-content
|
||||
.item-headline
|
||||
i.fas.fa-chart-line
|
||||
span= _p('aside.card_webinfo.headline')
|
||||
.webinfo
|
||||
if theme.aside.card_webinfo.post_count
|
||||
.webinfo-item
|
||||
.item-name= _p('aside.card_webinfo.article_name') + " :"
|
||||
.item-count= site.posts.length
|
||||
if theme.runtimeshow.enable
|
||||
.webinfo-item
|
||||
.item-name= _p('aside.card_webinfo.runtime.name') + " :"
|
||||
.item-count#runtimeshow(data-publishDate=date_xml(theme.runtimeshow.publish_date))
|
||||
if theme.wordcount.enable && theme.wordcount.total_wordcount
|
||||
.webinfo-item
|
||||
.item-name=_p('aside.card_webinfo.site_wordcount') + " :"
|
||||
.item-count=totalcount(site)
|
||||
if theme.busuanzi.site_uv
|
||||
.webinfo-item
|
||||
.item-name= _p('aside.card_webinfo.site_uv_name') + " :"
|
||||
.item-count#busuanzi_value_site_uv
|
||||
if theme.busuanzi.site_pv
|
||||
.webinfo-item
|
||||
.item-name= _p('aside.card_webinfo.site_pv_name') + " :"
|
||||
.item-count#busuanzi_value_site_pv
|
||||
if theme.aside.card_webinfo.last_push_date
|
||||
.webinfo-item
|
||||
.item-name= _p('aside.card_webinfo.last_push_date.name') + " :"
|
||||
.item-count#last-push-date(data-lastPushDate=date_xml(Date.now()))
|
||||
if theme.aside.card_webinfo.enable
|
||||
.card-widget.card-webinfo
|
||||
.card-content
|
||||
.item-headline
|
||||
i.fas.fa-chart-line
|
||||
span= _p('aside.card_webinfo.headline')
|
||||
.webinfo
|
||||
if theme.aside.card_webinfo.post_count
|
||||
.webinfo-item
|
||||
.item-name= _p('aside.card_webinfo.article_name') + " :"
|
||||
.item-count= site.posts.length
|
||||
if theme.runtimeshow.enable
|
||||
.webinfo-item
|
||||
.item-name= _p('aside.card_webinfo.runtime.name') + " :"
|
||||
.item-count#runtimeshow(data-publishDate=date_xml(theme.runtimeshow.publish_date))
|
||||
if theme.wordcount.enable && theme.wordcount.total_wordcount
|
||||
.webinfo-item
|
||||
.item-name=_p('aside.card_webinfo.site_wordcount') + " :"
|
||||
.item-count=totalcount(site)
|
||||
if theme.busuanzi.site_uv
|
||||
.webinfo-item
|
||||
.item-name= _p('aside.card_webinfo.site_uv_name') + " :"
|
||||
.item-count#busuanzi_value_site_uv
|
||||
if theme.busuanzi.site_pv
|
||||
.webinfo-item
|
||||
.item-name= _p('aside.card_webinfo.site_pv_name') + " :"
|
||||
.item-count#busuanzi_value_site_pv
|
||||
if theme.aside.card_webinfo.last_push_date
|
||||
.webinfo-item
|
||||
.item-name= _p('aside.card_webinfo.last_push_date.name') + " :"
|
||||
.item-count#last-push-date(data-lastPushDate=date_xml(Date.now()))
|
||||
|
||||
|
||||
@@ -1,28 +1,17 @@
|
||||
#aside_content.aside_content
|
||||
if theme.aside.card_author.enable
|
||||
!=partial('includes/widget/card_author', {}, {cache:theme.fragment_cache})
|
||||
if theme.aside.card_announcement.enable
|
||||
!=partial('includes/widget/card_announcement', {}, {cache:theme.fragment_cache})
|
||||
!=partial('includes/widget/card_author', {}, {cache:theme.fragment_cache})
|
||||
!=partial('includes/widget/card_announcement', {}, {cache:theme.fragment_cache})
|
||||
.sticky_layout
|
||||
if is_post()
|
||||
if showToc
|
||||
include ./card_post_toc.pug
|
||||
if theme.aside.card_recent_post.enable
|
||||
!=partial('includes/widget/card_recent_post', {}, {cache:theme.fragment_cache})
|
||||
if theme.ad && theme.ad.aside
|
||||
!=partial('includes/widget/card_ad', {}, {cache:theme.fragment_cache})
|
||||
!=partial('includes/widget/card_recent_post', {}, {cache:theme.fragment_cache})
|
||||
!=partial('includes/widget/card_ad', {}, {cache:theme.fragment_cache})
|
||||
else
|
||||
if theme.aside.card_recent_post.enable
|
||||
!=partial('includes/widget/card_recent_post', {}, {cache:theme.fragment_cache})
|
||||
if theme.ad && theme.ad.aside
|
||||
!=partial('includes/widget/card_ad', {}, {cache:theme.fragment_cache})
|
||||
if theme.newest_comments.enable
|
||||
!=partial('includes/widget/card_newest_comment', {}, {cache:theme.fragment_cache})
|
||||
if theme.aside.card_categories.enable
|
||||
!=partial('includes/widget/card_categories', {}, {cache:theme.fragment_cache})
|
||||
if theme.aside.card_tags.enable
|
||||
!=partial('includes/widget/card_tags', {}, {cache:theme.fragment_cache})
|
||||
if theme.aside.card_archives.enable
|
||||
!=partial('includes/widget/card_archives', {}, {cache:theme.fragment_cache})
|
||||
if theme.aside.card_webinfo.enable
|
||||
!=partial('includes/widget/card_webinfo', {}, {cache:theme.fragment_cache})
|
||||
!=partial('includes/widget/card_recent_post', {}, {cache:theme.fragment_cache})
|
||||
!=partial('includes/widget/card_ad', {}, {cache:theme.fragment_cache})
|
||||
!=partial('includes/widget/card_newest_comment', {}, {cache:theme.fragment_cache})
|
||||
!=partial('includes/widget/card_categories', {}, {cache:theme.fragment_cache})
|
||||
!=partial('includes/widget/card_tags', {}, {cache:theme.fragment_cache})
|
||||
!=partial('includes/widget/card_archives', {}, {cache:theme.fragment_cache})
|
||||
!=partial('includes/widget/card_webinfo', {}, {cache:theme.fragment_cache})
|
||||
@@ -19,7 +19,7 @@ block content
|
||||
|
||||
//- ad
|
||||
if theme.ad && theme.ad.post
|
||||
.post-ad!=theme.ad.post
|
||||
.ads-wrap!=theme.ad.post
|
||||
|
||||
include includes/pagination.pug
|
||||
if theme.related_post && theme.related_post.enable
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "hexo-theme-butterfly",
|
||||
"version": "3.3.0",
|
||||
"version": "3.4.0-b1",
|
||||
"description": "A Simple and Card UI Design theme for Hexo",
|
||||
"main": "package.json",
|
||||
"scripts": {
|
||||
@@ -26,7 +26,7 @@
|
||||
"hexo-renderer-stylus": "^2.0.1",
|
||||
"hexo-renderer-pug": "^1.0.0"
|
||||
},
|
||||
"homepage": "https://demo.jerryc.me/",
|
||||
"homepage": "https://butterfly.js.org/",
|
||||
"author": "Jerry <wong@jerryc.me>",
|
||||
"license": "Apache-2.0"
|
||||
}
|
||||
|
||||
@@ -65,11 +65,11 @@ hexo.extend.helper.register('aside_categories', function (categories, options) {
|
||||
|
||||
result += '</a>'
|
||||
|
||||
result += '</li>'
|
||||
|
||||
if (child) {
|
||||
result += `<ul class="card-category-list child">${child}</ul>`
|
||||
}
|
||||
|
||||
result += '</li>'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ function galleryGroup (args) {
|
||||
|
||||
return `
|
||||
<figure class="gallery-group">
|
||||
<img class="gallery-group-img" src='${img}'>
|
||||
<img class="gallery-group-img" src='${img}' alt="Group Image Gallery">
|
||||
<figcaption>
|
||||
<div class="gallery-group-name">${name}</div>
|
||||
<p>${desrc}</p>
|
||||
|
||||
@@ -44,7 +44,7 @@ function hideBlock (args, content) {
|
||||
group += '"'
|
||||
|
||||
return `<div class="hide-block"><button type="button" class="hide-button button--animated" ${group}>${display}
|
||||
</button><span class="hide-content">${hexo.render.renderSync({ text: content, engine: 'markdown' })}</span></div>`
|
||||
</button><div class="hide-content">${hexo.render.renderSync({ text: content, engine: 'markdown' })}</div></div>`
|
||||
}
|
||||
|
||||
function hideToggle (args, content) {
|
||||
|
||||
@@ -44,7 +44,7 @@ function postTabs (args, content) {
|
||||
const icon = tabIcon.trim()
|
||||
tabIcon.length > 0 && (tabIcon = `<i class="${icon}"${isOnlyicon}></i>`)
|
||||
|
||||
const toTop = '<button type="button" class="tab-to-top"><i class="fas fa-arrow-up"></i></button>'
|
||||
const toTop = '<button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button>'
|
||||
|
||||
const isActive = (tabActive > 0 && tabActive === tabId) || (tabActive === 0 && tabId === 1) ? ' active' : ''
|
||||
tabNav += `<li class="tab${isActive}"><button type="button" data-href="#${tabHref}">${tabIcon + tabCaption.trim()}</button></li>`
|
||||
|
||||
@@ -151,6 +151,13 @@ if hexo-config('avatar.effect') == true
|
||||
100%
|
||||
opacity: 1
|
||||
|
||||
@keyframes to_hide
|
||||
0%
|
||||
opacity: 1
|
||||
|
||||
100%
|
||||
opacity: 0
|
||||
|
||||
@keyframes ribbon_to_show
|
||||
0%
|
||||
opacity: 0
|
||||
@@ -196,4 +203,4 @@ if hexo-config('avatar.effect') == true
|
||||
transform: translateX(200px)
|
||||
|
||||
100%
|
||||
transform: translateX(0)
|
||||
transform: translateX(0)
|
||||
|
||||
@@ -57,16 +57,17 @@ body
|
||||
input::placeholder
|
||||
color: var(--font-color)
|
||||
|
||||
#web_bg
|
||||
position: fixed
|
||||
z-index: -999
|
||||
width: 100%
|
||||
height: 100%
|
||||
background: $web-bg
|
||||
background-attachment: local
|
||||
background-position: center
|
||||
background-size: cover
|
||||
background-repeat: no-repeat
|
||||
if $web-bg
|
||||
#web_bg
|
||||
position: fixed
|
||||
z-index: -999
|
||||
width: 100%
|
||||
height: 100%
|
||||
background: $web-bg
|
||||
background-attachment: local
|
||||
background-position: center
|
||||
background-size: cover
|
||||
background-repeat: no-repeat
|
||||
|
||||
h1,
|
||||
h2,
|
||||
@@ -198,20 +199,13 @@ img
|
||||
max-width: 100%
|
||||
transition: all .2s
|
||||
|
||||
img[src=''],
|
||||
img:not([src])
|
||||
opacity: 0
|
||||
&[src=''],
|
||||
&:not([src])
|
||||
opacity: 0
|
||||
|
||||
.img-alt
|
||||
margin: -.5rem 0 .5rem
|
||||
color: #858585
|
||||
|
||||
&:hover
|
||||
text-decoration: none !important
|
||||
|
||||
.post-ad
|
||||
margin: 2rem 0
|
||||
|
||||
.ad-height
|
||||
display: block !important
|
||||
height: auto !important
|
||||
text-decoration: none !important
|
||||
@@ -132,6 +132,7 @@ blockquote
|
||||
position: absolute
|
||||
right: 1.7rem
|
||||
opacity: 0
|
||||
transition: opacity .4s
|
||||
|
||||
.copy-button
|
||||
position: absolute
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
border-radius: 8px
|
||||
background: var(--card-bg)
|
||||
box-shadow: 0 4px 8px 6px rgba(7, 17, 27, .06)
|
||||
transition: all .3s
|
||||
transition: box-shadow .3s
|
||||
|
||||
&:hover
|
||||
box-shadow: 0 4px 12px 12px rgba(7, 17, 27, .15)
|
||||
@@ -265,23 +265,38 @@
|
||||
|
||||
// toc
|
||||
#card-toc
|
||||
+minWidth900()
|
||||
right: 0 !important
|
||||
|
||||
+maxWidth900()
|
||||
position: fixed
|
||||
right: 45px
|
||||
right: -100%
|
||||
bottom: 30px
|
||||
z-index: 100
|
||||
display: none
|
||||
max-height: calc(100% - 60px)
|
||||
width: $toc-mobile-width
|
||||
opacity: 0
|
||||
transform-origin: right bottom
|
||||
animation: toc-open .3s
|
||||
|
||||
.toc-child
|
||||
display: block !important
|
||||
// animation: toc-open .3s
|
||||
|
||||
.toc-content
|
||||
overflow-y: auto
|
||||
max-height: calc(100vh - 120px)
|
||||
|
||||
+maxWidth900()
|
||||
max-height: calc(100vh - 140px)
|
||||
|
||||
.toc-child
|
||||
display: none
|
||||
|
||||
+maxWidth900()
|
||||
display: block !important
|
||||
|
||||
.toc-item
|
||||
&.active
|
||||
.toc-child
|
||||
display: block
|
||||
|
||||
ol,
|
||||
li
|
||||
list-style: none
|
||||
|
||||
@@ -351,10 +351,10 @@ _:future,
|
||||
.menus_items
|
||||
display: none !important
|
||||
|
||||
#search_button span
|
||||
#search-button span
|
||||
display: none !important
|
||||
|
||||
#search_button
|
||||
#search-button
|
||||
display: inline
|
||||
padding: 0 0 0 .7rem
|
||||
|
||||
|
||||
@@ -275,3 +275,6 @@ no-beautify()
|
||||
color: $noticeOutdate-border
|
||||
content: '\f071'
|
||||
transform: translateY(-50%)
|
||||
|
||||
.ads-wrap
|
||||
margin: 2rem 0
|
||||
|
||||
@@ -106,7 +106,8 @@ if hexo-config('darkmode.enable') || hexo-config('display_mode') == 'dark'
|
||||
.error-img,
|
||||
#article-container iframe,
|
||||
img,
|
||||
.gist
|
||||
.gist,
|
||||
.ads-wrap
|
||||
filter: brightness(.8)
|
||||
|
||||
#aside_content .aside-list > .aside-list-item:not(:last-child)
|
||||
|
||||
@@ -43,6 +43,10 @@
|
||||
order: 2
|
||||
border-radius: 0 8px 8px 0
|
||||
|
||||
&.ads-wrap
|
||||
display: block !important
|
||||
height: auto !important
|
||||
|
||||
.post_cover
|
||||
overflow: hidden
|
||||
width: 45%
|
||||
|
||||
@@ -57,9 +57,6 @@
|
||||
color: $search-keyword-highlight
|
||||
font-weight: bold
|
||||
|
||||
.local-search-stats__hr
|
||||
display: none !important
|
||||
|
||||
.search-result-list
|
||||
overflow-y: auto
|
||||
max-height: 10.5rem
|
||||
|
||||
@@ -99,6 +99,9 @@ figure.gallery-group
|
||||
img
|
||||
opacity: 0
|
||||
|
||||
.img-alt
|
||||
display: none
|
||||
|
||||
.fancybox
|
||||
width: auto
|
||||
text-align: inherit
|
||||
@@ -10,6 +10,12 @@
|
||||
&.open
|
||||
display: none
|
||||
|
||||
& + div
|
||||
display: block
|
||||
|
||||
& + span
|
||||
display: inline
|
||||
|
||||
& > .hide-content
|
||||
display: none
|
||||
|
||||
@@ -41,6 +47,9 @@
|
||||
i
|
||||
transform: rotate(90deg)
|
||||
|
||||
& + div
|
||||
display: block
|
||||
|
||||
& > .hide-content
|
||||
display: none
|
||||
margin: 1.5rem 1.2rem
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
@import 'nib'
|
||||
if hexo-config('css_prefix')
|
||||
@import 'nib'
|
||||
|
||||
@import '_third-party/normalize.min.css'
|
||||
// project
|
||||
@import 'var'
|
||||
|
||||
@@ -1,61 +1,57 @@
|
||||
$(function () {
|
||||
const blogNameWidth = $('#site-name').width()
|
||||
const menusWidth = $('#menus').width()
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const blogNameWidth = document.getElementById('site-name').offsetWidth
|
||||
const menusWidth = document.getElementById('menus').offsetWidth
|
||||
|
||||
const adjustMenu = () => {
|
||||
const $nav = $('#nav')
|
||||
const $nav = document.getElementById('nav')
|
||||
let t
|
||||
if (window.innerWidth < 768) t = true
|
||||
else t = blogNameWidth + menusWidth > $nav.width() - 30
|
||||
else t = blogNameWidth + menusWidth > $nav.offsetWidth - 100
|
||||
|
||||
if (t) {
|
||||
$nav.addClass('hide-menu')
|
||||
$nav.classList.add('hide-menu')
|
||||
} else {
|
||||
$nav.removeClass('hide-menu')
|
||||
$nav.classList.remove('hide-menu')
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化header
|
||||
const initAdjust = () => {
|
||||
adjustMenu()
|
||||
$('#nav').addClass('show')
|
||||
document.getElementById('nav').classList.add('show')
|
||||
}
|
||||
|
||||
// sidebar menus
|
||||
const sidebarFn = () => {
|
||||
const $toggleMenu = $('#toggle-menu')
|
||||
const $mobileSidebarMenus = $('#sidebar-menus')
|
||||
const $menuMask = $('#menu-mask')
|
||||
const $body = $('body')
|
||||
const $toggleMenu = document.getElementById('toggle-menu')
|
||||
const $mobileSidebarMenus = document.getElementById('sidebar-menus')
|
||||
const $menuMask = document.getElementById('menu-mask')
|
||||
const $body = document.body
|
||||
|
||||
function openMobileSidebar () {
|
||||
btf.sidebarPaddingR()
|
||||
$body.css('overflow', 'hidden')
|
||||
$menuMask.fadeIn()
|
||||
$toggleMenu.removeClass('close').addClass('open')
|
||||
$mobileSidebarMenus.addClass('open')
|
||||
$body.style.overflow = 'hidden'
|
||||
btf.fadeIn($menuMask, 0.5)
|
||||
$mobileSidebarMenus.classList.add('open')
|
||||
}
|
||||
|
||||
function closeMobileSidebar () {
|
||||
$body.css({ overflow: '', 'padding-right': '' })
|
||||
$menuMask.fadeOut()
|
||||
$toggleMenu.removeClass('open').addClass('close')
|
||||
$mobileSidebarMenus.removeClass('open')
|
||||
$body.style.cssText = "overflow: ''; padding-right: ''"
|
||||
btf.fadeOut($menuMask, 0.5)
|
||||
$mobileSidebarMenus.classList.remove('open')
|
||||
}
|
||||
|
||||
$toggleMenu.on('click', function () {
|
||||
openMobileSidebar()
|
||||
})
|
||||
$toggleMenu.addEventListener('click', openMobileSidebar)
|
||||
|
||||
$menuMask.on('click touchstart', function (e) {
|
||||
if ($toggleMenu.hasClass('open')) {
|
||||
$menuMask.addEventListener('click', e => {
|
||||
if ($mobileSidebarMenus.classList.contains('open')) {
|
||||
closeMobileSidebar()
|
||||
}
|
||||
})
|
||||
|
||||
$(window).on('resize', function (e) {
|
||||
if (!$toggleMenu.is(':visible')) {
|
||||
if ($toggleMenu.hasClass('open')) closeMobileSidebar()
|
||||
window.addEventListener('resize', e => {
|
||||
if (btf.isHidden($toggleMenu)) {
|
||||
if ($mobileSidebarMenus.classList.contains('open')) closeMobileSidebar()
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -64,8 +60,8 @@ $(function () {
|
||||
* 首頁top_img底下的箭頭
|
||||
*/
|
||||
const scrollDownInIndex = () => {
|
||||
$('#scroll-down').on('click', function () {
|
||||
btf.scrollToDest('#content-inner')
|
||||
document.getElementById('scroll-down').addEventListener('click', function () {
|
||||
btf.scrollToDest(document.getElementById('content-inner').offsetTop, 300)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -78,7 +74,7 @@ $(function () {
|
||||
const isHighlightLang = GLOBAL_CONFIG.highlight.highlightLang
|
||||
const isHighlightShrink = GLOBAL_CONFIG_SITE.isHighlightShrink
|
||||
const isShowTool = isHighlightCopy || isHighlightLang || isHighlightShrink !== undefined
|
||||
const $figureHighlight = GLOBAL_CONFIG.highlight.plugin === 'highlighjs' ? $('figure.highlight') : $('pre[class*="language-"]')
|
||||
const $figureHighlight = GLOBAL_CONFIG.highlight.plugin === 'highlighjs' ? document.querySelectorAll('figure.highlight') : document.querySelectorAll('pre[class*="language-"]')
|
||||
|
||||
if (isShowTool && $figureHighlight.length) {
|
||||
const isPrismjs = GLOBAL_CONFIG.highlight.plugin === 'prismjs'
|
||||
@@ -95,88 +91,100 @@ $(function () {
|
||||
highlightCopyEle = '<div class="copy-notice"></div><i class="fas fa-paste copy-button"></i>'
|
||||
}
|
||||
|
||||
const copy = (text, ctx) => {
|
||||
if (document.queryCommandSupported && document.queryCommandSupported('copy')) {
|
||||
document.execCommand('copy')
|
||||
if (GLOBAL_CONFIG.Snackbar !== undefined) {
|
||||
btf.snackbarShow(GLOBAL_CONFIG.copy.success)
|
||||
} else {
|
||||
const prevEle = ctx.previousElementSibling
|
||||
prevEle.innerText = GLOBAL_CONFIG.copy.success
|
||||
prevEle.style.opacity = 1
|
||||
setTimeout(() => { prevEle.style.opacity = 0 }, 700)
|
||||
}
|
||||
} else {
|
||||
if (GLOBAL_CONFIG.Snackbar !== undefined) {
|
||||
btf.snackbarShow(GLOBAL_CONFIG.copy.noSupport)
|
||||
} else {
|
||||
ctx.previousElementSibling.innerText = GLOBAL_CONFIG.copy.noSupport
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// click events
|
||||
const highlightCopyFn = (ele) => {
|
||||
const $buttonParent = ele.parentNode
|
||||
$buttonParent.classList.add('copy-true')
|
||||
const selection = window.getSelection()
|
||||
const range = document.createRange()
|
||||
if (isPrismjs) range.selectNodeContents($buttonParent.querySelectorAll('pre code')[0])
|
||||
else range.selectNodeContents($buttonParent.querySelectorAll('table .code pre')[0])
|
||||
selection.removeAllRanges()
|
||||
selection.addRange(range)
|
||||
const text = selection.toString()
|
||||
copy(text, ele.lastChild)
|
||||
selection.removeAllRanges()
|
||||
$buttonParent.classList.remove('copy-true')
|
||||
}
|
||||
|
||||
const highlightShrinkFn = (ele) => {
|
||||
const $nextEle = [...ele.parentNode.children].slice(1)
|
||||
ele.firstChild.classList.toggle('closed')
|
||||
if (btf.isHidden($nextEle[0])) {
|
||||
$nextEle.forEach(e => { e.style.display = 'block' })
|
||||
} else {
|
||||
$nextEle.forEach(e => { e.style.display = 'none' })
|
||||
}
|
||||
}
|
||||
|
||||
const highlightToolsFn = function (e) {
|
||||
const $target = e.target.classList
|
||||
if ($target.contains('expand')) highlightShrinkFn(this)
|
||||
else if ($target.contains('copy-button')) highlightCopyFn(this)
|
||||
}
|
||||
|
||||
const createEle = () => {
|
||||
const newEle = document.createElement('div')
|
||||
newEle.className = `highlight-tools ${highlightShrinkClass}`
|
||||
newEle.addEventListener('click', highlightToolsFn)
|
||||
return newEle
|
||||
}
|
||||
|
||||
if (isHighlightLang) {
|
||||
if (isPrismjs) {
|
||||
$figureHighlight.each(function () {
|
||||
const $this = $(this)
|
||||
const langName = $this.attr('data-language') !== undefined ? $this.attr('data-language') : 'Code'
|
||||
$figureHighlight.forEach(function (item) {
|
||||
const langName = item.getAttribute('data-language') !== undefined ? item.getAttribute('data-language') : 'Code'
|
||||
const highlightLangEle = `<div class="code-lang">${langName}</div>`
|
||||
$this.wrap('<figure class="highlight"></figure>').before(`<div class="highlight-tools ${highlightShrinkClass}">${highlightShrinkEle + highlightLangEle + highlightCopyEle}</div>`)
|
||||
btf.wrap(item, 'figure', '', 'highlight')
|
||||
const newEle = createEle()
|
||||
newEle.innerHTML = highlightShrinkEle + highlightLangEle + highlightCopyEle
|
||||
item.parentNode.insertBefore(newEle, item)
|
||||
})
|
||||
} else {
|
||||
$figureHighlight.each(function (i, o) {
|
||||
const $this = $(this)
|
||||
let langName = $this.attr('class').split(' ')[1]
|
||||
$figureHighlight.forEach(function (item) {
|
||||
let langName = item.getAttribute('class').split(' ')[1]
|
||||
if (langName === 'plain' || langName === undefined) langName = 'Code'
|
||||
const highlightLangEle = `<div class="code-lang">${langName}</div>`
|
||||
$this.prepend(`<div class="highlight-tools ${highlightShrinkClass}">${highlightShrinkEle + highlightLangEle + highlightCopyEle}</div>`)
|
||||
const newEle = createEle()
|
||||
newEle.innerHTML = highlightShrinkEle + highlightLangEle + highlightCopyEle
|
||||
item.insertBefore(newEle, item.firstChild)
|
||||
})
|
||||
}
|
||||
} else {
|
||||
const ele = `<div class="highlight-tools ${highlightShrinkClass}">${highlightShrinkEle + highlightCopyEle}</div>`
|
||||
if (isPrismjs) $figureHighlight.wrap('<figure class="highlight"></figure>').before(ele)
|
||||
else $figureHighlight.prepend(ele)
|
||||
}
|
||||
|
||||
/**
|
||||
* 代碼收縮
|
||||
*/
|
||||
|
||||
if (isHighlightShrink !== undefined) {
|
||||
$('.highlight-tools >.expand').on('click', function () {
|
||||
const $this = $(this)
|
||||
const $table = $this.parent().nextAll()
|
||||
$this.toggleClass('closed')
|
||||
$table.is(':visible') ? $table.css('display', 'none') : $table.css('display', 'block')
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 代碼copy
|
||||
*/
|
||||
if (isHighlightCopy) {
|
||||
const copy = function (text, ctx) {
|
||||
if (document.queryCommandSupported && document.queryCommandSupported('copy')) {
|
||||
document.execCommand('copy')
|
||||
if (GLOBAL_CONFIG.Snackbar !== undefined) {
|
||||
btf.snackbarShow(GLOBAL_CONFIG.copy.success)
|
||||
} else {
|
||||
$(ctx).prev('.copy-notice')
|
||||
.text(GLOBAL_CONFIG.copy.success)
|
||||
.animate({
|
||||
opacity: 1
|
||||
}, 450, function () {
|
||||
setTimeout(function () {
|
||||
$(ctx).prev('.copy-notice').animate({
|
||||
opacity: 0
|
||||
}, 650)
|
||||
}, 400)
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if (GLOBAL_CONFIG.Snackbar !== undefined) {
|
||||
btf.snackbarShow(GLOBAL_CONFIG.copy.noSupport)
|
||||
} else {
|
||||
$(ctx).prev('.copy-notice').text(GLOBAL_CONFIG.copy.noSupport)
|
||||
}
|
||||
}
|
||||
if (isPrismjs) {
|
||||
$figureHighlight.forEach(function (item) {
|
||||
btf.wrap(item, 'figure', '', 'highlight')
|
||||
const newEle = createEle()
|
||||
newEle.innerHTML = highlightShrinkEle + highlightCopyEle
|
||||
item.parentNode.insertBefore(newEle, item)
|
||||
})
|
||||
} else {
|
||||
$figureHighlight.forEach(function (item) {
|
||||
const newEle = createEle()
|
||||
newEle.innerHTML = highlightShrinkEle + highlightCopyEle
|
||||
item.insertBefore(newEle, item.firstChild)
|
||||
})
|
||||
}
|
||||
|
||||
// click events
|
||||
$('.highlight-tools >.copy-button').on('click', function () {
|
||||
const $buttonParent = $(this).parents('figure.highlight')
|
||||
$buttonParent.addClass('copy-true')
|
||||
const selection = window.getSelection()
|
||||
const range = document.createRange()
|
||||
if (isPrismjs) range.selectNodeContents($buttonParent.find('> pre code')[0])
|
||||
else range.selectNodeContents($buttonParent.find('table .code pre')[0])
|
||||
selection.removeAllRanges()
|
||||
selection.addRange(range)
|
||||
const text = selection.toString()
|
||||
copy(text, this)
|
||||
selection.removeAllRanges()
|
||||
$buttonParent.removeClass('copy-true')
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -185,24 +193,27 @@ $(function () {
|
||||
* PhotoFigcaption
|
||||
*/
|
||||
function addPhotoFigcaption () {
|
||||
const images = $('#article-container img').not('.justified-gallery img')
|
||||
images.each(function (i, o) {
|
||||
const $this = $(o)
|
||||
if ($this.attr('alt')) {
|
||||
const t = $('<div class="img-alt is-center">' + $this.attr('alt') + '</div>')
|
||||
$this.after(t)
|
||||
document.querySelectorAll('#article-container img').forEach(function (item) {
|
||||
const parentEle = item.parentNode
|
||||
if (!parentEle.parentNode.classList.contains('justified-gallery')) {
|
||||
const ele = document.createElement('div')
|
||||
ele.className = 'img-alt is-center'
|
||||
ele.textContent = item.getAttribute('alt')
|
||||
parentEle.insertBefore(ele, item.nextSibling)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* justified-gallery 圖庫排版
|
||||
* 需要 jQuery
|
||||
*/
|
||||
|
||||
let detectJgJsLoad = false
|
||||
const runJustifiedGallery = function () {
|
||||
const $justifiedGallery = $('.justified-gallery')
|
||||
let $justifiedGallery = document.querySelectorAll('#article-container .justified-gallery')
|
||||
if ($justifiedGallery.length) {
|
||||
$justifiedGallery = $($justifiedGallery)
|
||||
const $imgList = $justifiedGallery.find('img')
|
||||
$imgList.unwrap()
|
||||
if ($imgList.length) {
|
||||
@@ -214,8 +225,8 @@ $(function () {
|
||||
|
||||
if (detectJgJsLoad) btf.initJustifiedGallery($justifiedGallery)
|
||||
else {
|
||||
$('head').append(`<link rel="stylesheet" type="text/css" href="${GLOBAL_CONFIG.justifiedGallery.css}">`)
|
||||
$.getScript(`${GLOBAL_CONFIG.justifiedGallery.js}`, function () {
|
||||
$('head').append(`<link rel="stylesheet" type="text/css" href="${GLOBAL_CONFIG.source.justifiedGallery.css}">`)
|
||||
$.getScript(`${GLOBAL_CONFIG.source.justifiedGallery.js}`, function () {
|
||||
btf.initJustifiedGallery($justifiedGallery)
|
||||
})
|
||||
detectJgJsLoad = true
|
||||
@@ -228,21 +239,37 @@ $(function () {
|
||||
*/
|
||||
const addLightBox = function () {
|
||||
if (GLOBAL_CONFIG.lightbox === 'fancybox') {
|
||||
const images = $('#article-container img:not(.gallery-group-img)').not($('a>img'))
|
||||
images.each(function (i, o) {
|
||||
const lazyloadSrc = $(o).attr('data-lazy-src') ? $(o).attr('data-lazy-src') : $(o).attr('src')
|
||||
const dataCaption = $(o).attr('alt') ? $(o).attr('alt') : ''
|
||||
$(o).wrap(`<a href="${lazyloadSrc}" data-fancybox="group" data-caption="${dataCaption}" class="fancybox"></a>`)
|
||||
})
|
||||
const images = document.querySelectorAll('#article-container :not(a):not(.gallery-group) > img, #article-container > img')
|
||||
if (images.length) {
|
||||
btf.isJqueryLoad(() => {
|
||||
const runFancybox = (ele) => {
|
||||
ele.each(function (i, o) {
|
||||
const $this = $(o)
|
||||
const lazyloadSrc = $this.attr('data-lazy-src') || $this.attr('src')
|
||||
const dataCaption = $this.attr('alt') || ''
|
||||
$this.wrap(`<a href="${lazyloadSrc}" data-fancybox="group" data-caption="${dataCaption}" class="fancybox"></a>`)
|
||||
})
|
||||
|
||||
$().fancybox({
|
||||
selector: '[data-fancybox]',
|
||||
loop: true,
|
||||
transitionEffect: 'slide',
|
||||
protect: true,
|
||||
buttons: ['slideShow', 'fullScreen', 'thumbs', 'close'],
|
||||
hash: false
|
||||
})
|
||||
$().fancybox({
|
||||
selector: '[data-fancybox]',
|
||||
loop: true,
|
||||
transitionEffect: 'slide',
|
||||
protect: true,
|
||||
buttons: ['slideShow', 'fullScreen', 'thumbs', 'close'],
|
||||
hash: false
|
||||
})
|
||||
}
|
||||
|
||||
if (typeof $.fancybox === 'undefined') {
|
||||
$('head').append(`<link rel="stylesheet" type="text/css" href="${GLOBAL_CONFIG.source.fancybox.css}">`)
|
||||
$.getScript(`${GLOBAL_CONFIG.source.fancybox.js}`, function () {
|
||||
runFancybox($(images))
|
||||
})
|
||||
} else {
|
||||
runFancybox($(images))
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
const zoom = mediumZoom(document.querySelectorAll('#article-container :not(a)>img'))
|
||||
zoom.on('open', function (event) {
|
||||
@@ -260,36 +287,36 @@ $(function () {
|
||||
const scrollFn = function () {
|
||||
let initTop = 0
|
||||
let isChatShow = true
|
||||
const $rightside = $('#rightside')
|
||||
const $nav = $('#nav')
|
||||
const $rightside = document.getElementById('rightside')
|
||||
const $nav = document.getElementById('nav')
|
||||
const isChatBtnHide = typeof chatBtnHide === 'function'
|
||||
const isChatBtnShow = typeof chatBtnShow === 'function'
|
||||
$(window).scroll(btf.throttle(function (event) {
|
||||
const currentTop = $(this).scrollTop()
|
||||
window.addEventListener('scroll', btf.throttle(function (e) {
|
||||
const currentTop = window.scrollY || document.documentElement.scrollTop
|
||||
const isDown = scrollDirection(currentTop)
|
||||
if (currentTop > 56) {
|
||||
if (isDown) {
|
||||
if ($nav.hasClass('visible')) $nav.removeClass('visible')
|
||||
if ($nav.classList.contains('visible')) $nav.classList.remove('visible')
|
||||
if (isChatBtnShow && isChatShow === true) {
|
||||
chatBtnHide()
|
||||
isChatShow = false
|
||||
}
|
||||
} else {
|
||||
if (!$nav.hasClass('visible')) $nav.addClass('visible')
|
||||
if (!$nav.classList.contains('visible')) $nav.classList.add('visible')
|
||||
if (isChatBtnHide && isChatShow === false) {
|
||||
window.chatBtnShow()
|
||||
chatBtnShow()
|
||||
isChatShow = true
|
||||
}
|
||||
}
|
||||
$nav.addClass('fixed')
|
||||
if ($rightside.css('opacity') === '0') {
|
||||
$rightside.css({ opacity: '1', transform: 'translateX(-38px)' })
|
||||
$nav.classList.add('fixed')
|
||||
if (window.getComputedStyle($rightside).getPropertyValue('opacity') === '0') {
|
||||
$rightside.style.cssText = 'opacity: 1; transform: translateX(-38px)'
|
||||
}
|
||||
} else {
|
||||
if (currentTop === 0) {
|
||||
$nav.removeClass('fixed').removeClass('visible')
|
||||
$nav.classList.remove('fixed', 'visible')
|
||||
}
|
||||
$rightside.css({ opacity: '', transform: '' })
|
||||
$rightside.style.cssText = "opacity: ''; transform: ''"
|
||||
}
|
||||
}, 200))
|
||||
|
||||
@@ -305,40 +332,29 @@ $(function () {
|
||||
* toc
|
||||
*/
|
||||
const tocFn = function () {
|
||||
const $cardTocLayout = $('#card-toc')
|
||||
const $cardToc = $cardTocLayout.find('.toc-content')
|
||||
const $tocChild = $cardToc.find('.toc-child')
|
||||
const $tocLink = $cardToc.find('.toc-link')
|
||||
const $article = $('#article-container')
|
||||
|
||||
$tocChild.hide()
|
||||
const $cardTocLayout = document.getElementById('card-toc')
|
||||
const $cardToc = $cardTocLayout.getElementsByClassName('toc-content')[0]
|
||||
const $tocLink = $cardToc.querySelectorAll('.toc-link')
|
||||
const $article = document.getElementById('article-container')
|
||||
|
||||
// main of scroll
|
||||
$(window).scroll(btf.throttle(function (event) {
|
||||
const currentTop = $(this).scrollTop()
|
||||
window.addEventListener('scroll', btf.throttle(function (e) {
|
||||
const currentTop = window.scrollY || document.documentElement.scrollTop
|
||||
scrollPercent(currentTop)
|
||||
findHeadPosition(currentTop)
|
||||
}, 100))
|
||||
|
||||
// expand toc-item
|
||||
const expandToc = function ($item) {
|
||||
if ($item.is(':visible')) {
|
||||
return
|
||||
}
|
||||
$item.fadeIn(400)
|
||||
}
|
||||
|
||||
const scrollPercent = function (currentTop) {
|
||||
const docHeight = $article.height()
|
||||
const winHeight = $(window).height()
|
||||
const headerHeight = $article.offset().top
|
||||
const contentMath = (docHeight > winHeight) ? (docHeight - winHeight) : ($(document).height() - winHeight)
|
||||
const docHeight = $article.clientHeight
|
||||
const winHeight = document.documentElement.clientHeight
|
||||
const headerHeight = $article.offsetTop
|
||||
const contentMath = (docHeight > winHeight) ? (docHeight - winHeight) : (document.documentElement.scrollHeight - winHeight)
|
||||
const scrollPercent = (currentTop - headerHeight) / (contentMath)
|
||||
const scrollPercentRounded = Math.round(scrollPercent * 100)
|
||||
const percentage = (scrollPercentRounded > 100) ? 100
|
||||
: (scrollPercentRounded <= 0) ? 0
|
||||
: scrollPercentRounded
|
||||
$cardToc.attr('progress-percentage', percentage)
|
||||
$cardToc.setAttribute('progress-percentage', percentage)
|
||||
}
|
||||
|
||||
// anchor
|
||||
@@ -351,94 +367,86 @@ $(function () {
|
||||
|
||||
const mobileToc = {
|
||||
open: () => {
|
||||
$cardTocLayout.css('display', 'block')
|
||||
$cardTocLayout.style.cssText = 'animation: toc-open .3s; opacity: 1; right: 45px'
|
||||
},
|
||||
|
||||
close: () => {
|
||||
$cardTocLayout.css('animation', 'toc-close .2s')
|
||||
$cardTocLayout.style.animation = 'toc-close .2s'
|
||||
setTimeout(() => {
|
||||
$cardTocLayout.css({ display: '', animation: '' })
|
||||
$cardTocLayout.style.cssText = "opacity:''; animation: ''; right: ''"
|
||||
}, 100)
|
||||
}
|
||||
}
|
||||
|
||||
$('#mobile-toc-button').on('click', () => {
|
||||
if ($cardTocLayout.is(':visible')) {
|
||||
mobileToc.close()
|
||||
} else {
|
||||
mobileToc.open()
|
||||
}
|
||||
document.getElementById('mobile-toc-button').addEventListener('click', () => {
|
||||
if (window.getComputedStyle($cardTocLayout).getPropertyValue('opacity') === '0') mobileToc.open()
|
||||
else mobileToc.close()
|
||||
})
|
||||
|
||||
// toc元素點擊
|
||||
$tocLink.on('click', function (e) {
|
||||
$cardToc.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
btf.scrollToDest(decodeURI($(this).attr('href')))
|
||||
const $target = e.target.classList.contains('toc-link')
|
||||
? e.target
|
||||
: e.target.parentElement
|
||||
btf.scrollToDest(document.querySelector(decodeURI($target.getAttribute('href'))).offsetTop, 300)
|
||||
if (window.innerWidth < 900) {
|
||||
mobileToc.close()
|
||||
}
|
||||
})
|
||||
|
||||
const autoScrollToc = function (currentTop, item) {
|
||||
const activePosition = item.offset().top
|
||||
const $tocContent = $cardToc
|
||||
const sidebarScrollTop = $tocContent.scrollTop()
|
||||
if (activePosition > (currentTop + $(window).height() - 100)) {
|
||||
$tocContent.scrollTop(sidebarScrollTop + 100)
|
||||
const autoScrollToc = function (item) {
|
||||
const activePosition = item.getBoundingClientRect().top
|
||||
const sidebarScrollTop = $cardToc.scrollTop
|
||||
if (activePosition > (document.documentElement.clientHeight - 100)) {
|
||||
$cardToc.scrollTop = sidebarScrollTop + 150
|
||||
}
|
||||
if (activePosition < currentTop + 100) {
|
||||
$tocContent.scrollTop(sidebarScrollTop - 100)
|
||||
if (activePosition < 100) {
|
||||
$cardToc.scrollTop = sidebarScrollTop - 150
|
||||
}
|
||||
}
|
||||
|
||||
// find head position & add active class
|
||||
// DOM Hierarchy:
|
||||
// ol.toc > (li.toc-item, ...)
|
||||
// li.toc-item > (a.toc-link, ol.toc-2child > (li.toc-item, ...))
|
||||
const list = $article.find('h1,h2,h3,h4,h5,h6')
|
||||
|
||||
const list = $article.querySelectorAll('h1,h2,h3,h4,h5,h6')
|
||||
let detectItem = ''
|
||||
const findHeadPosition = function (top) {
|
||||
// assume that we are not in the post page if no TOC link be found,
|
||||
// thus no need to update the status
|
||||
if ($tocLink.length === 0) {
|
||||
return false
|
||||
}
|
||||
|
||||
let currentId = ''
|
||||
list.each(function () {
|
||||
const head = $(this)
|
||||
if (top > head.offset().top - 70) {
|
||||
currentId = '#' + encodeURI($(this).attr('id'))
|
||||
let currentIndex = ''
|
||||
|
||||
list.forEach(function (ele, index) {
|
||||
if (top > ele.offsetTop - 70) {
|
||||
currentId = '#' + encodeURI(ele.getAttribute('id'))
|
||||
currentIndex = index
|
||||
}
|
||||
})
|
||||
|
||||
if (detectItem === currentIndex) return
|
||||
|
||||
if (currentId === '') {
|
||||
$tocLink.removeClass('active')
|
||||
$tocChild.hide()
|
||||
$cardToc.querySelectorAll('.active').forEach(i => { i.classList.remove('active') })
|
||||
detectItem = currentIndex
|
||||
return
|
||||
}
|
||||
|
||||
const currentActive = $tocLink.filter('.active')
|
||||
if (currentId && currentActive.attr('href') !== currentId) {
|
||||
if (isAnchor) updateAnchor(currentId)
|
||||
detectItem = currentIndex
|
||||
|
||||
$tocLink.removeClass('active')
|
||||
$cardToc.querySelectorAll('.active').forEach(item => { item.classList.remove('active') })
|
||||
const currentActive = $tocLink[currentIndex]
|
||||
currentActive.classList.add('active')
|
||||
if (isAnchor) updateAnchor(currentId)
|
||||
|
||||
const _this = $tocLink.filter('[href="' + currentId + '"]')
|
||||
_this.addClass('active')
|
||||
autoScrollToc(top, _this)
|
||||
setTimeout(function () {
|
||||
autoScrollToc(currentActive)
|
||||
}, 0)
|
||||
|
||||
const parents = _this.parents('.toc-child')
|
||||
// Returned list is in reverse order of the DOM elements
|
||||
// Thus `parents.last()` is the outermost .toc-child container
|
||||
// i.e. list of subsections
|
||||
const topLink = (parents.length > 0) ? parents.last() : _this
|
||||
expandToc(topLink.closest('.toc-item').find('.toc-child'))
|
||||
topLink
|
||||
// Find all top-level .toc-item containers, i.e. sections
|
||||
// excluding the currently active one
|
||||
.closest('.toc-item').siblings('.toc-item')
|
||||
// Hide their respective list of subsections
|
||||
.find('.toc-child').hide()
|
||||
let parent = currentActive.parentNode
|
||||
|
||||
for (; !parent.matches('.toc'); parent = parent.parentNode) {
|
||||
if (parent.matches('li')) parent.classList.add('active')
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -446,17 +454,11 @@ $(function () {
|
||||
/**
|
||||
* Rightside
|
||||
*/
|
||||
|
||||
const $rightsideEle = $('#rightside')
|
||||
|
||||
// read-mode
|
||||
$rightsideEle.on('click', '#readmode', function () {
|
||||
$('body').toggleClass('read-mode')
|
||||
})
|
||||
|
||||
// Switch Between Light And Dark Mode
|
||||
if ($('#darkmode').length) {
|
||||
const switchReadMode = function () {
|
||||
const rightSideFn = {
|
||||
switchReadMode: () => { // read-mode
|
||||
document.body.classList.toggle('read-mode')
|
||||
},
|
||||
switchDarkMode: () => { // Switch Between Light And Dark Mode
|
||||
const nowMode = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light'
|
||||
if (nowMode === 'light') {
|
||||
activateDarkMode()
|
||||
@@ -467,30 +469,46 @@ $(function () {
|
||||
saveToLocal.set('theme', 'light', 2)
|
||||
GLOBAL_CONFIG.Snackbar !== undefined && btf.snackbarShow(GLOBAL_CONFIG.Snackbar.night_to_day)
|
||||
}
|
||||
}
|
||||
|
||||
$rightsideEle.on('click', '#darkmode', () => {
|
||||
switchReadMode()
|
||||
// handle some cases
|
||||
typeof utterancesTheme === 'function' && utterancesTheme()
|
||||
typeof FB === 'object' && window.loadFBComment()
|
||||
window.DISQUS && $('#disqus_thread').children().length && setTimeout(() => window.disqusReset(), 200)
|
||||
})
|
||||
window.DISQUS && document.getElementById('disqus_thread').children.length && setTimeout(() => window.disqusReset(), 200)
|
||||
},
|
||||
showOrHideBtn: () => { // rightside 點擊設置 按鈕 展開
|
||||
document.getElementById('rightside-config-hide').classList.toggle('show')
|
||||
},
|
||||
scrollToTop: () => { // Back to top
|
||||
btf.scrollToDest(0, 500)
|
||||
},
|
||||
hideAsideBtn: () => { // Hide aside
|
||||
const $htmlDom = document.documentElement.classList
|
||||
$htmlDom.contains('hide-aside')
|
||||
? saveToLocal.set('aside-status', 'show', 2)
|
||||
: saveToLocal.set('aside-status', 'hide', 2)
|
||||
$htmlDom.toggle('hide-aside')
|
||||
}
|
||||
}
|
||||
|
||||
// rightside 點擊設置 按鈕 展開
|
||||
$rightsideEle.on('click', '#rightside_config', () => $('#rightside-config-hide').toggleClass('show'))
|
||||
|
||||
// Back to top
|
||||
$rightsideEle.on('click', '#go-up', () => btf.scrollToDest('body'))
|
||||
|
||||
$rightsideEle.on('click', '#hide-aside-btn', () => {
|
||||
const $htmlDom = $(document.documentElement)
|
||||
if ($htmlDom.hasClass('hide-aside')) {
|
||||
$htmlDom.removeClass('hide-aside')
|
||||
saveToLocal.set('aside-status', 'show', 2)
|
||||
} else {
|
||||
$htmlDom.addClass('hide-aside')
|
||||
saveToLocal.set('aside-status', 'hide', 2)
|
||||
document.getElementById('rightside').addEventListener('click', function (e) {
|
||||
const $target = e.target.id || e.target.parentNode.id
|
||||
switch ($target) {
|
||||
case 'go-up':
|
||||
rightSideFn.scrollToTop()
|
||||
break
|
||||
case 'rightside_config':
|
||||
rightSideFn.showOrHideBtn()
|
||||
break
|
||||
case 'readmode':
|
||||
rightSideFn.switchReadMode()
|
||||
break
|
||||
case 'darkmode':
|
||||
rightSideFn.switchDarkMode()
|
||||
break
|
||||
case 'hide-aside-btn':
|
||||
rightSideFn.hideAsideBtn()
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
})
|
||||
|
||||
@@ -500,16 +518,23 @@ $(function () {
|
||||
* 解決menus在觸摸屏下,滑動屏幕menus_item_child不消失的問題(手機hover的bug)
|
||||
*/
|
||||
const clickFnOfSubMenu = function () {
|
||||
$('#sidebar-menus .expand').on('click', function () {
|
||||
$(this).parents('.menus_item').find('> .menus_item_child').slideToggle()
|
||||
$(this).toggleClass('hide')
|
||||
document.querySelectorAll('#sidebar-menus .expand').forEach(function (e) {
|
||||
e.addEventListener('click', function () {
|
||||
this.classList.toggle('hide')
|
||||
const $dom = this.parentNode.nextElementSibling
|
||||
if (btf.isHidden($dom)) {
|
||||
$dom.style.display = 'block'
|
||||
} else {
|
||||
$dom.style.display = 'none'
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
$(window).on('touchmove', function (e) {
|
||||
const $menusChild = $('#nav .menus_item_child')
|
||||
if ($menusChild.is(':visible')) {
|
||||
$menusChild.css('display', 'none')
|
||||
}
|
||||
window.addEventListener('touchmove', function (e) {
|
||||
const $menusChild = document.querySelectorAll('#nav .menus_item_child')
|
||||
$menusChild.forEach(item => {
|
||||
if (!btf.isHidden(item)) item.style.display = 'none'
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -542,10 +567,10 @@ $(function () {
|
||||
* 網頁運行時間
|
||||
*/
|
||||
const addRuntime = () => {
|
||||
const $runtimeCount = $('#runtimeshow')
|
||||
if ($runtimeCount.length) {
|
||||
const publishDate = $runtimeCount.attr('data-publishDate')
|
||||
$runtimeCount.text(btf.diffDate(publishDate) + ' ' + GLOBAL_CONFIG.runtime)
|
||||
const $runtimeCount = document.getElementById('runtimeshow')
|
||||
if ($runtimeCount !== null) {
|
||||
const publishDate = $runtimeCount.getAttribute('data-publishDate')
|
||||
$runtimeCount.innerText = btf.diffDate(publishDate) + ' ' + GLOBAL_CONFIG.runtime
|
||||
}
|
||||
}
|
||||
|
||||
@@ -553,11 +578,10 @@ $(function () {
|
||||
* 最後一次更新時間
|
||||
*/
|
||||
const addLastPushDate = () => {
|
||||
const $lastPushDateItem = $('#last-push-date')
|
||||
if ($lastPushDateItem.length) {
|
||||
const lastPushDate = $lastPushDateItem.attr('data-lastPushDate')
|
||||
const diffDay = btf.diffDate(lastPushDate, true)
|
||||
$lastPushDateItem.text(diffDay)
|
||||
const $lastPushDateItem = document.getElementById('last-push-date')
|
||||
if ($lastPushDateItem !== null) {
|
||||
const lastPushDate = $lastPushDateItem.getAttribute('data-lastPushDate')
|
||||
$lastPushDateItem.innerText = btf.diffDate(lastPushDate, true)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -565,85 +589,101 @@ $(function () {
|
||||
* table overflow
|
||||
*/
|
||||
const addTableWrap = function () {
|
||||
const $table = $('#article-container table').not($('figure.highlight > table'))
|
||||
$table.each(function () {
|
||||
$(this).wrap('<div class="table-wrap"></div>')
|
||||
})
|
||||
const $table = document.querySelectorAll('#article-container :not(.highlight) > table, #article-container > table')
|
||||
if ($table.length) {
|
||||
$table.forEach(item => {
|
||||
btf.wrap(item, 'div', '', 'table-wrap')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* tag-hide
|
||||
*/
|
||||
const clickFnOfTagHide = function () {
|
||||
const $hideInline = $('.hide-button')
|
||||
const $hideInline = document.querySelectorAll('#article-container .hide-button')
|
||||
if ($hideInline.length) {
|
||||
$hideInline.on('click', function (e) {
|
||||
const $this = $(this)
|
||||
const $hideContent = $(this).next('.hide-content')
|
||||
$this.toggleClass('open')
|
||||
$hideContent.toggle()
|
||||
if ($this.hasClass('open')) {
|
||||
if ($hideContent.find('.justified-gallery').length > 0) {
|
||||
btf.initJustifiedGallery($hideContent.find('.justified-gallery'))
|
||||
$hideInline.forEach(function (item) {
|
||||
item.addEventListener('click', function (e) {
|
||||
const $this = this
|
||||
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'))
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const tabsFn = {
|
||||
clickFnOfTabs: function () {
|
||||
const $tab = $('#article-container .tabs')
|
||||
$tab.find('.tab > button:not(.tab-to-top)').on('click', function (e) {
|
||||
const $this = $(this)
|
||||
const $tabItem = $this.parent()
|
||||
document.querySelectorAll('#article-container .tab > button').forEach(function (item) {
|
||||
item.addEventListener('click', function (e) {
|
||||
const $this = this
|
||||
const $tabItem = $this.parentNode
|
||||
|
||||
if (!$tabItem.hasClass('active')) {
|
||||
const $tabContent = $this.parents('.nav-tabs').next()
|
||||
$tabItem.siblings('.active').removeClass('active')
|
||||
$tabItem.addClass('active')
|
||||
const tabId = $this.attr('data-href')
|
||||
$tabContent.find('> .tab-item-content').removeClass('active')
|
||||
$tabContent.find(`> ${tabId}`).addClass('active')
|
||||
const $isTabJustifiedGallery = $tabContent.find(tabId).find('.justified-gallery')
|
||||
if ($isTabJustifiedGallery.length > 0) {
|
||||
btf.initJustifiedGallery($isTabJustifiedGallery)
|
||||
if (!$tabItem.classList.contains('active')) {
|
||||
const $tabContent = $tabItem.parentNode.nextElementSibling
|
||||
btf.siblings($tabItem, 'active')[0].classList.remove('active')
|
||||
$tabItem.classList.add('active')
|
||||
const tabId = $this.getAttribute('data-href').replace('#', '')
|
||||
const childList = [...$tabContent.children]
|
||||
childList.forEach(item => {
|
||||
if (item.id === tabId) item.classList.add('active')
|
||||
else item.classList.remove('active')
|
||||
})
|
||||
const $isTabJustifiedGallery = $tabContent.querySelectorAll(`#${tabId} .justified-gallery`)
|
||||
if ($isTabJustifiedGallery.length > 0) {
|
||||
btf.initJustifiedGallery($isTabJustifiedGallery)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
backToTop: () => {
|
||||
const backToTopBtn = $('#article-container .tabs .tab-to-top')
|
||||
backToTopBtn.on('click', function () {
|
||||
btf.scrollToDest($(this).parents('.tabs'))
|
||||
document.querySelectorAll('#article-container .tabs .tab-to-top').forEach(function (item) {
|
||||
item.addEventListener('click', function () {
|
||||
btf.scrollToDest(btf.getParents(this, '.tabs').offsetTop, 300)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const toggleCardCategory = function () {
|
||||
const $cardCategory = $('#aside-cat-list .card-category-list-item.parent i')
|
||||
$cardCategory.on('click', function (e) {
|
||||
e.preventDefault()
|
||||
$(this).toggleClass('expand').parents('.parent').next().slideToggle(300)
|
||||
})
|
||||
const $cardCategory = document.querySelectorAll('#aside-cat-list .card-category-list-item.parent i')
|
||||
if ($cardCategory.length > 0) {
|
||||
$cardCategory.forEach(function (item) {
|
||||
item.addEventListener('click', function (e) {
|
||||
e.preventDefault()
|
||||
const $this = this
|
||||
$this.classList.toggle('expand')
|
||||
const $parentEle = $this.parentNode.nextElementSibling
|
||||
if (btf.isHidden($parentEle)) {
|
||||
$parentEle.style.display = 'block'
|
||||
} else {
|
||||
$parentEle.style.display = 'none'
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const switchComments = function () {
|
||||
let switchDone = false
|
||||
$('#comment-switch > .switch-btn').on('click', function () {
|
||||
const $btn = $(this)
|
||||
$btn.hasClass('move') ? $btn.removeClass('move') : $btn.addClass('move')
|
||||
$('#post-comment > .comment-wrap > div').each(function (i, o) {
|
||||
const $this = $(o)
|
||||
if ($this.is(':visible')) {
|
||||
$this.hide()
|
||||
const $switchBtn = document.querySelector('#comment-switch > .switch-btn')
|
||||
$switchBtn && $switchBtn.addEventListener('click', function () {
|
||||
this.classList.toggle('move')
|
||||
document.querySelectorAll('#post-comment > .comment-wrap > div').forEach(function (item) {
|
||||
if (btf.isHidden(item)) {
|
||||
item.style.cssText = 'display: block;animation: tabshow .5s'
|
||||
} else {
|
||||
$this.css({
|
||||
display: 'block',
|
||||
animation: 'tabshow .5s'
|
||||
})
|
||||
item.style.cssText = "display: none;animation: ''"
|
||||
}
|
||||
})
|
||||
|
||||
if (!switchDone && typeof loadOtherComment === 'function') {
|
||||
switchDone = true
|
||||
loadOtherComment()
|
||||
@@ -655,11 +695,14 @@ $(function () {
|
||||
const data = GLOBAL_CONFIG.noticeOutdate
|
||||
var diffDay = btf.diffDate(GLOBAL_CONFIG_SITE.postUpdate)
|
||||
if (diffDay >= data.limitDay) {
|
||||
const code = `<div class="post-outdate-notice">${data.messagePrev + ' ' + diffDay + ' ' + data.messageNext}</div>`
|
||||
const ele = document.createElement('div')
|
||||
ele.className = 'post-outdate-notice'
|
||||
ele.textContent = data.messagePrev + ' ' + diffDay + ' ' + data.messageNext
|
||||
const $targetEle = document.getElementById('article-container')
|
||||
if (data.position === 'top') {
|
||||
$('#article-container').prepend(code)
|
||||
$targetEle.insertBefore(ele, $targetEle.firstChild)
|
||||
} else {
|
||||
$('#article-container').append(code)
|
||||
$targetEle.appendChild(ele)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -673,17 +716,16 @@ $(function () {
|
||||
}
|
||||
|
||||
const relativeDate = function (selector) {
|
||||
selector.each((i, o) => {
|
||||
const $this = $(o)
|
||||
const timeVal = $this.attr('datetime')
|
||||
$this.text(btf.diffDate(timeVal, true)).css('display', 'inline')
|
||||
selector.forEach(item => {
|
||||
const $this = item
|
||||
const timeVal = $this.getAttribute('datetime')
|
||||
$this.innerText = btf.diffDate(timeVal, true)
|
||||
$this.style.display = 'inline'
|
||||
})
|
||||
}
|
||||
|
||||
const unRefreshFn = function () {
|
||||
$(window).on('resize', function () {
|
||||
adjustMenu()
|
||||
})
|
||||
window.addEventListener('resize', adjustMenu)
|
||||
|
||||
clickFnOfSubMenu()
|
||||
GLOBAL_CONFIG.islazyload && lazyloadImg()
|
||||
@@ -696,9 +738,9 @@ $(function () {
|
||||
if (GLOBAL_CONFIG_SITE.isPost) {
|
||||
GLOBAL_CONFIG_SITE.isToc && tocFn()
|
||||
GLOBAL_CONFIG.noticeOutdate !== undefined && addPostOutdateNotice()
|
||||
GLOBAL_CONFIG.relativeDate.post && relativeDate($('#post-meta time'))
|
||||
GLOBAL_CONFIG.relativeDate.post && relativeDate(document.querySelectorAll('#post-meta time'))
|
||||
} else {
|
||||
GLOBAL_CONFIG.relativeDate.homepage && relativeDate($('#recent-posts time'))
|
||||
GLOBAL_CONFIG.relativeDate.homepage && relativeDate(document.querySelectorAll('#recent-posts time'))
|
||||
GLOBAL_CONFIG.runtime && addRuntime()
|
||||
addLastPushDate()
|
||||
toggleCardCategory()
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
$(function () {
|
||||
window.addEventListener('load', () => {
|
||||
const openSearch = () => {
|
||||
$('body').css({ width: '100%', overflow: 'hidden' })
|
||||
$('#algolia-search .search-dialog').css('display', 'block')
|
||||
$('.ais-search-box--input').focus()
|
||||
$('#search-mask').fadeIn()
|
||||
document.body.style.cssText = 'width: 100%;overflow: hidden'
|
||||
document.querySelector('#algolia-search .search-dialog').style.display = 'block'
|
||||
document.querySelector('#algolia-search .ais-search-box--input').focus()
|
||||
btf.fadeIn(document.getElementById('search-mask'), 0.5)
|
||||
// shortcut: ESC
|
||||
document.addEventListener('keydown', function f (event) {
|
||||
if (event.code === 'Escape') {
|
||||
@@ -14,30 +14,23 @@ $(function () {
|
||||
}
|
||||
|
||||
const closeSearch = () => {
|
||||
$('body').css({ width: '', overflow: '' })
|
||||
$('#algolia-search .search-dialog').css({
|
||||
animation: 'search_close .5s'
|
||||
})
|
||||
|
||||
setTimeout(function () {
|
||||
$('#algolia-search .search-dialog').css({
|
||||
animation: '',
|
||||
display: 'none'
|
||||
})
|
||||
}, 500)
|
||||
|
||||
$('#search-mask').fadeOut()
|
||||
document.body.style.cssText = "width: '';overflow: ''"
|
||||
const $searchDialog = document.querySelector('#algolia-search .search-dialog')
|
||||
$searchDialog.style.animation = 'search_close .5s'
|
||||
setTimeout(() => { $searchDialog.style.cssText = "display: none; animation: ''" }, 500)
|
||||
btf.fadeOut(document.getElementById('search-mask'), 0.5)
|
||||
}
|
||||
|
||||
const searchClickFn = () => {
|
||||
$('a.social-icon.search').on('click', openSearch)
|
||||
$('#search-mask, .search-close-button').on('click touchstart', closeSearch)
|
||||
document.querySelector('#search-button > .search').addEventListener('click', openSearch)
|
||||
document.getElementById('search-mask').addEventListener('click', closeSearch)
|
||||
document.querySelector('#algolia-search .search-close-button').addEventListener('click', closeSearch)
|
||||
}
|
||||
|
||||
searchClickFn()
|
||||
|
||||
window.addEventListener('pjax:complete', function () {
|
||||
closeSearch()
|
||||
getComputedStyle(document.querySelector('#algolia-search .search-dialog')).display === 'block' && closeSearch()
|
||||
searchClickFn()
|
||||
})
|
||||
|
||||
@@ -55,9 +48,9 @@ $(function () {
|
||||
hitsPerPage: algolia.hits.per_page || 10
|
||||
},
|
||||
searchFunction: function (helper) {
|
||||
const searchInput = $('#algolia-search-input').find('input')
|
||||
const searchInput = document.querySelector('#algolia-search-input input')
|
||||
|
||||
if (searchInput.val()) {
|
||||
if (searchInput.value) {
|
||||
helper.search()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,14 @@
|
||||
$(function () {
|
||||
window.addEventListener('load', () => {
|
||||
let loadFlag = false
|
||||
const openSearch = function () {
|
||||
$('body').css({
|
||||
width: '100%',
|
||||
overflow: 'hidden'
|
||||
})
|
||||
$('#local-search .search-dialog').css('display', 'block')
|
||||
$('#local-search-input input').focus()
|
||||
$('#search-mask').fadeIn()
|
||||
document.body.style.cssText = 'width: 100%;overflow: hidden'
|
||||
document.querySelector('#local-search .search-dialog').style.display = 'block'
|
||||
document.querySelector('#local-search-input input').focus()
|
||||
btf.fadeIn(document.getElementById('search-mask'), 0.5)
|
||||
if (!loadFlag) {
|
||||
search(GLOBAL_CONFIG.localSearch.path)
|
||||
loadFlag = true
|
||||
}
|
||||
|
||||
// shortcut: ESC
|
||||
document.addEventListener('keydown', function f (event) {
|
||||
if (event.code === 'Escape') {
|
||||
@@ -23,60 +19,48 @@ $(function () {
|
||||
}
|
||||
|
||||
const closeSearch = function () {
|
||||
$('body').css({
|
||||
width: '',
|
||||
overflow: ''
|
||||
})
|
||||
$('#local-search .search-dialog').css({
|
||||
animation: 'search_close .5s'
|
||||
})
|
||||
|
||||
setTimeout(function () {
|
||||
$('#local-search .search-dialog').css({
|
||||
animation: '',
|
||||
display: 'none'
|
||||
})
|
||||
}, 500)
|
||||
|
||||
$('#search-mask').fadeOut()
|
||||
document.body.style.cssText = "width: '';overflow: ''"
|
||||
const $searchDialog = document.querySelector('#local-search .search-dialog')
|
||||
$searchDialog.style.animation = 'search_close .5s'
|
||||
setTimeout(() => { $searchDialog.style.cssText = "display: none; animation: ''" }, 500)
|
||||
btf.fadeOut(document.getElementById('search-mask'), 0.5)
|
||||
}
|
||||
|
||||
// click function
|
||||
const searchClickFn = () => {
|
||||
$('a.social-icon.search').on('click', openSearch)
|
||||
$('#search-mask, .search-close-button').on('click', closeSearch)
|
||||
document.querySelector('#search-button > .search').addEventListener('click', openSearch)
|
||||
document.getElementById('search-mask').addEventListener('click', closeSearch)
|
||||
document.querySelector('#local-search .search-close-button').addEventListener('click', closeSearch)
|
||||
}
|
||||
|
||||
searchClickFn()
|
||||
|
||||
// pjax
|
||||
window.addEventListener('pjax:complete', function () {
|
||||
$('#local-search .search-dialog').is(':visible') && closeSearch()
|
||||
getComputedStyle(document.querySelector('#local-search .search-dialog')).display === 'block' && closeSearch()
|
||||
searchClickFn()
|
||||
})
|
||||
|
||||
function search (path) {
|
||||
$.ajax({
|
||||
url: GLOBAL_CONFIG.root + path,
|
||||
dataType: 'xml',
|
||||
success: function (xmlResponse) {
|
||||
// get the contents from search data
|
||||
const datas = $('entry', xmlResponse).map(function () {
|
||||
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) {
|
||||
return {
|
||||
title: $('title', this).text(),
|
||||
content: $('content', this).text(),
|
||||
url: $('url', this).text()
|
||||
title: item.querySelector('title').textContent,
|
||||
content: item.querySelector('content').textContent,
|
||||
url: item.querySelector('url').textContent
|
||||
}
|
||||
}).get()
|
||||
})
|
||||
|
||||
const $input = $('#local-search-input input')[0]
|
||||
const $resultContent = $('#local-hits')[0]
|
||||
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) {
|
||||
$('.local-search-stats__hr').hide()
|
||||
return
|
||||
}
|
||||
if (this.value.trim().length <= 0) return
|
||||
let count = 0
|
||||
// perform local searching
|
||||
datas.forEach(function (data) {
|
||||
@@ -141,7 +125,6 @@ $(function () {
|
||||
|
||||
str += '<div class="local-search__hit-item"><a href="' + dataUrl + '" class="search-result-title">' + dataTitle + '</a>'
|
||||
count += 1
|
||||
$('.local-search-stats__hr').show()
|
||||
|
||||
if (dataContent !== '') {
|
||||
str += '<p class="search-result">' + matchContent + '...</p>'
|
||||
@@ -158,7 +141,6 @@ $(function () {
|
||||
$resultContent.innerHTML = str
|
||||
window.pjax && window.pjax.refresh($resultContent)
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* eslint-disable no-undef */
|
||||
(function () {
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const translate = GLOBAL_CONFIG.translate
|
||||
const snackbarData = GLOBAL_CONFIG.Snackbar
|
||||
const defaultEncoding = translate.defaultEncoding // 網站默認語言,1: 繁體中文, 2: 簡體中文
|
||||
@@ -96,4 +96,4 @@
|
||||
}
|
||||
translateInitialization()
|
||||
document.addEventListener('pjax:complete', translateInitialization)
|
||||
})()
|
||||
})
|
||||
|
||||
@@ -56,23 +56,10 @@ var btf = {
|
||||
const clientWidth = document.body.clientWidth
|
||||
const paddingRight = innerWidth - clientWidth
|
||||
if (innerWidth !== clientWidth) {
|
||||
$('body').css('padding-right', paddingRight)
|
||||
document.body.style.paddingRight = paddingRight + 'px'
|
||||
}
|
||||
},
|
||||
|
||||
scrollToDest: name => {
|
||||
const scrollOffset = $(name).offset().top
|
||||
let offset
|
||||
if ($(window).scrollTop() > scrollOffset) {
|
||||
offset = 65
|
||||
} else {
|
||||
offset = 0
|
||||
}
|
||||
$('body,html').animate({
|
||||
scrollTop: scrollOffset - offset
|
||||
})
|
||||
},
|
||||
|
||||
snackbarShow: (text, showAction, duration) => {
|
||||
const sa = (typeof showAction !== 'undefined') ? showAction : false
|
||||
const dur = (typeof duration !== 'undefined') ? duration : 2000
|
||||
@@ -88,6 +75,9 @@ var btf = {
|
||||
},
|
||||
|
||||
initJustifiedGallery: function (selector) {
|
||||
if (!(selector instanceof jQuery)) {
|
||||
selector = $(selector)
|
||||
}
|
||||
selector.each(function (i, o) {
|
||||
if ($(this).is(':visible')) {
|
||||
$(this).justifiedGallery({
|
||||
@@ -145,5 +135,118 @@ var btf = {
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
scrollToDest: (pos, time) => {
|
||||
if (pos < 0 || time < 0) {
|
||||
return
|
||||
}
|
||||
var currentPos = window.scrollY || window.screenTop
|
||||
|
||||
if (currentPos > pos) pos = pos - 65
|
||||
var start = null
|
||||
time = time || 500
|
||||
window.requestAnimationFrame(function step (currentTime) {
|
||||
start = !start ? 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)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
fadeIn: (ele, time) => {
|
||||
ele.style.cssText = `display:block;animation: to_show ${time}s`
|
||||
},
|
||||
|
||||
fadeOut: (ele, time) => {
|
||||
ele.addEventListener('animationend', function f () {
|
||||
ele.style.cssText = "display: none; animation: '' "
|
||||
ele.removeEventListener('animationend', f)
|
||||
})
|
||||
ele.style.animation = `to_hide ${time}s`
|
||||
},
|
||||
|
||||
getParents: (elem, selector) => {
|
||||
// polyfill
|
||||
if (!Element.prototype.matches) {
|
||||
Element.prototype.matches =
|
||||
Element.prototype.matchesSelector ||
|
||||
Element.prototype.mozMatchesSelector ||
|
||||
Element.prototype.msMatchesSelector ||
|
||||
Element.prototype.oMatchesSelector ||
|
||||
Element.prototype.webkitMatchesSelector ||
|
||||
function (s) {
|
||||
const matches = (this.document || this.ownerDocument).querySelectorAll(s)
|
||||
let i = matches.length
|
||||
while (--i >= 0 && matches.item(i) !== this) {}
|
||||
return i > -1
|
||||
}
|
||||
}
|
||||
|
||||
for (; elem && elem !== document; elem = elem.parentNode) {
|
||||
if (elem.matches(selector)) return elem
|
||||
}
|
||||
return null
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {*} ele
|
||||
* @param {*} selector class name
|
||||
*/
|
||||
siblings: (ele, selector) => {
|
||||
return [...ele.parentNode.children].filter((child) => {
|
||||
if (selector) {
|
||||
return child !== ele && child.classList.contains(selector)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {*} selector
|
||||
* @param {*} eleType the type of create element
|
||||
* @param {*} id id
|
||||
* @param {*} cn class name
|
||||
*/
|
||||
wrap: function (selector, eleType, id = null, cn = null) {
|
||||
const creatEle = document.createElement(eleType)
|
||||
if (id) creatEle.id = id
|
||||
if (cn) creatEle.className = cn
|
||||
selector.parentNode.insertBefore(creatEle, selector)
|
||||
creatEle.appendChild(selector)
|
||||
},
|
||||
|
||||
unwrap: function (el) {
|
||||
const elParentNode = el.parentNode
|
||||
if (elParentNode !== document.body) {
|
||||
elParentNode.parentNode.insertBefore(el, elParentNode)
|
||||
elParentNode.parentNode.removeChild(elParentNode)
|
||||
}
|
||||
},
|
||||
|
||||
isJqueryLoad: (fn) => {
|
||||
if (typeof jQuery === 'undefined') {
|
||||
getScript(GLOBAL_CONFIG.source.jQuery).then(fn)
|
||||
} else {
|
||||
fn()
|
||||
}
|
||||
},
|
||||
|
||||
isHidden: (ele) => ele.offsetHeight === 0 && ele.offsetWidth === 0
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user