window.encrypt = (str) => window.btoa(unescape(encodeURIComponent(str)))
window.decrypt = (str) => decodeURIComponent(escape(window.atob(str)))
const commonContext = {
/* 初始化widget */
initWidget() {
const $columnRight = $('.columns .column-right')
const $columnRightShadow = $('.columns .column-right-shadow')
$('.widget.recent-comments .reply .link').html((i, html) => Utils.renderedEmojiHtml(html))
// 实现将右边widget拷贝的左边
if ($columnRight.length && $columnRightShadow.length && !$columnRightShadow[0].children.length) {
for (const child of $columnRight[0].children) {
$columnRightShadow[0].append(child.cloneNode(true))
}
}
},
/* 初始化悬浮操作按钮 */
initActions() {
const $bulletScreen = $('.actions>.bullet-screen')
if (localStorage.getItem('stop-bullet-screen') === 'true') {
$bulletScreen.addClass('stop-bullet-screen')
}
if ($('halo-comment[bullet-screen]').length !== 0) {
$bulletScreen.removeClass('is-hidden-all')
}
const applyStopBulletScreen = (stopBulletScreenValue) => {
$('halo-comment[bullet-screen]').each(function () {
const shadowDom = this.shadowRoot.getElementById('halo-comment')
if (stopBulletScreenValue) {
$(shadowDom).attr('stop-bullet-screen', 'true')
} else {
$(shadowDom).removeAttr('stop-bullet-screen')
}
})
if (stopBulletScreenValue) {
$bulletScreen.addClass('stop-bullet-screen')
} else {
$bulletScreen.removeClass('stop-bullet-screen')
}
localStorage.setItem('stop-bullet-screen', stopBulletScreenValue)
}
$bulletScreen.on('click', () => {
let stopBulletScreen = localStorage.getItem('stop-bullet-screen') || false
applyStopBulletScreen(stopBulletScreen.toString() !== 'true')
})
},
/* 初始化目录和公告模块 */
initTocAndNotice() {
const {pathname} = location
window.tocPjax && window.tocPjax()
let hideToc = $('.widget.toc .card-content ul').length === 0
let hideNotice = (DreamConfig.notice_show_mode === 'toc' && !hideToc)
|| (DreamConfig.notice_show_mode === 'index' && pathname !== '/')
if (hideToc) {
$('.widget.toc,.action-toc').addClass('is-hidden-all')
} else {
$('.widget.toc,.action-toc').removeClass('is-hidden-all')
}
if (hideNotice) {
$('.widget.notice').addClass('is-hidden-all')
} else {
$('.widget.notice').removeClass('is-hidden-all')
}
},
/* 更新横幅大图的文字描述 */
initBanner() {
const $bannerInfoDesc = $('.banner-info-desc')
if ($bannerInfoDesc.length === 0) return
const bannerDesc = $bannerInfoDesc.text()
$bannerInfoDesc.text('')
let currentBannerDesc = ''
let isWrite = true
let id
const updateDesc = function () {
let num = currentBannerDesc.length
if (isWrite && num < bannerDesc.length) {
currentBannerDesc += bannerDesc.charAt(num)
$bannerInfoDesc.text(currentBannerDesc)
} else if (!isWrite && num > 0) {
currentBannerDesc = currentBannerDesc.slice(0, num - 1)
$bannerInfoDesc.text(currentBannerDesc)
} else {
clearInterval(id)
isWrite = !isWrite
id = setInterval(updateDesc, isWrite ? 500 : 80)
}
}
id = setInterval(updateDesc, isWrite ? 500 : 80)
},
/* 激活图片预览功能 */
initGallery() {
// 用链接和标题包装图像
$('.main-content img:not(.not-gallery)').each(function () {
if ($(this).parents('[data-fancybox],mew-photos').length === 0) {
$(this).wrap(`
${this.alt ? `
${this.alt}
` : ''}
`)
}
})
},
/* 初始化主题模式(仅用户模式) */
initMode() {
let isNight = localStorage.getItem('night') || false
const applyNight = (isNightValue) => {
if (isNightValue) {
document.documentElement.classList.add('night')
} else {
document.documentElement.classList.remove('night')
}
$('halo-comment').each(function () {
const shadowDom = this.shadowRoot.getElementById('halo-comment')
$(shadowDom)[`${isNightValue ? 'add' : 'remove'}Class`]('night')
})
localStorage.setItem('night', isNightValue)
isNight = isNightValue
}
$('#toggle-mode').on('click', () => applyNight(isNight.toString() !== 'true'))
if (DreamConfig.default_theme === 'system') {
window.matchMedia('(prefers-color-scheme: dark)')
.addListener((event) => applyNight(event.matches))
}
},
/* 导航条高亮 */
initNavbar() {
const $nav_menus = $('.navbar-nav a')
const $nav_side_menus = $('.panel-side-menu .link')
let activeIndex = 0
const {href, pathname} = location
if (pathname && pathname !== '/') {
for (let i = 0; i < $nav_menus.length; i++) {
const cur_href = $nav_menus[i].getAttribute('href')
if (pathname.includes(cur_href) || href.includes(cur_href)) {
activeIndex = i
if (pathname === cur_href || href === cur_href) break
}
}
}
// 高亮PC端
const $curMenu = $nav_menus.eq(activeIndex)
$curMenu.addClass('current')
if ($curMenu.parents('.item-dropdown').length) {
$curMenu
.parents('.item-dropdown')
.find('.item-dropdown-link a')
.addClass('current')
}
// 高亮移动端
$nav_side_menus.eq(activeIndex).addClass('current')
},
/* 激活导航栏全局下拉框功能 */
initDropMenu() {
$('.item-dropdown').each(function (index, item) {
const menu = $(this).find('.item-dropdown-menu')
const trigger = $(item).attr('trigger') || 'click'
const placement = $(item).attr('placement') || $(this).height() || 0
menu.css('top', placement)
if (trigger === 'hover') {
$(this).hover(
() => $(this).addClass('active'),
() => $(this).removeClass('active')
)
} else {
$(this).on('click', function (e) {
e.stopPropagation()
$(this).toggleClass('active')
$(document).one('click', () => $(this).removeClass('active'))
e.stopPropagation()
})
menu.on('click', (e) => e.stopPropagation())
}
})
},
/* 处理滚动 */
initScroll() {
let initTop = 0
// true:上划,false:下滑
function scrollDirection(currentTop) {
const result = currentTop > initTop
initTop = currentTop
return result
}
const handleScroll = () => {
const scrollTop = $(document).scrollTop()
const direction = scrollDirection(scrollTop)
const $body = $('body')
const $actions = $('.actions')
if (scrollTop > 50 && direction) {
$body.addClass('move-up')
} else {
$body.removeClass('move-up')
}
if (scrollTop > 100) {
$actions.addClass('show')
} else {
$actions.removeClass('show')
}
}
document.addEventListener('scroll', handleScroll)
},
/* 搜索框弹窗 */
searchDialog() {
const $result = $('.navbar-search .result')
$('.navbar-search .input').on('click', function (e) {
e.stopPropagation()
$result.addClass('active')
})
$(document).on('click', function () {
$result.removeClass('active')
})
},
/* 小屏幕伸缩侧边栏,包含导航或者目录 */
drawerMobile() {
$('.navbar-slideicon').on('click', function (e) {
e.stopPropagation()
/* 关闭搜索框 */
$('.navbar-searchout').removeClass('active')
/* 处理开启关闭状态 */
const $html = $('html')
const $mask = $('.navbar-mask')
const $slide_out = $('.navbar-slideout')
if ($slide_out.hasClass('active')) {
$html.removeClass('disable-scroll')
$mask.removeClass('active slideout')
$slide_out.removeClass('active')
} else {
$html.addClass('disable-scroll')
$mask.addClass('active slideout')
$slide_out.addClass('active')
}
})
$('.action-toc').on('click', function (e) {
e.stopPropagation()
/* 关闭搜索框 */
$('.navbar-searchout').removeClass('active')
/* 处理开启关闭状态 */
const $html = $('html')
const $mask = $('.navbar-mask')
const $slide_out = $('.navbar-slideout')
if ($slide_out.hasClass('active')) {
$html.removeClass('disable-scroll')
$mask.removeClass('active slideout')
$slide_out.removeClass('active slideout-toc')
} else {
$html.addClass('disable-scroll')
$mask.addClass('active slideout')
$slide_out.addClass('active slideout-toc')
}
})
},
/* 激活全局返回顶部功能 */
back2Top() {
$('#back-to-top').on('click', function () {
$('body, html').animate({scrollTop: 0}, 400)
})
},
/* 小屏幕搜索框 */
searchMobile() {
$('.navbar-searchicon').on('click', function (e) {
e.stopPropagation()
/* 关闭侧边栏 */
$('.navbar-slideout').removeClass('active')
/* 处理开启关闭状态 */
const $html = $('html')
const $mask = $('.navbar-mask')
const $above = $('.navbar-above')
const $search_out = $('.navbar-searchout')
if ($search_out.hasClass('active')) {
$html.removeClass('disable-scroll')
$mask.removeClass('active slideout')
$search_out.removeClass('active')
$above.removeClass('solid')
} else {
$html.addClass('disable-scroll')
$mask.addClass('active')
$above.addClass('solid')
$search_out.addClass('active')
}
})
},
/* 点击遮罩层关闭 */
maskClose() {
$('.navbar-mask')
.on('click', function (e) {
e.stopPropagation()
$('html').removeClass('disable-scroll')
$('.navbar-mask').removeClass('active slideout')
$('.navbar-searchout').removeClass('active')
$('.navbar-slideout').removeClass('active slideout-toc')
$('.navbar-above').removeClass('solid')
})
.on('touchmove', (e) => e.preventDefault)
$('.navbar .toc-content')
.on('click', function (e) {
e.stopPropagation()
$('html').removeClass('disable-scroll')
$('.navbar-mask').removeClass('active slideout')
$('.navbar-slideout').removeClass('active slideout-toc')
})
},
/* 移动端侧边栏菜单手风琴 */
sideMenuMobile() {
$('.navbar-slideout-menu .current')
.parents('.panel-body')
.show()
.siblings('.panel')
.addClass('in')
$('.navbar-slideout-menu .panel').on('click', function (e) {
e.stopPropagation()
const $this = $(this)
const panelBox = $this.parent().parent()
/* 清除全部内容 */
panelBox.find('.panel').not($this).removeClass('in')
panelBox
.find('.panel-body')
.not($this.siblings('.panel-body'))
.stop()
.hide('fast')
/* 激活当前的内容 */
$this.toggleClass('in').siblings('.panel-body').stop().toggle('fast')
})
},
/* 初始化事件 */
initEvent() {
let $body = $('body')
function closeSelect(elem) {
let $elem = $(elem)
const closeSelect = $elem.attr('data-close')
return closeSelect && closeSelect.trim() !== '' ? $elem.closest(closeSelect.trim()) : $elem
}
$body.on('click', '.click-close', function (e) {
e.stopPropagation()
closeSelect(this).remove()
})
$body.on('click', '.click-animation-close', function (e) {
e.stopPropagation()
let selectElem = closeSelect(this)
selectElem.addClass('close-animation')
setTimeout(() => selectElem.remove(), 300)
})
},
/* 离屏提示 */
offscreenTip() {
if (Utils.isMobile() || (!DreamConfig.document_hidden_title && !DreamConfig.document_visible_title)) return
const originTitle = document.title
let timer = null
document.addEventListener('visibilitychange', function () {
if (document.hidden) {
DreamConfig.document_hidden_title && (document.title = DreamConfig.document_hidden_title)
clearTimeout(timer)
} else {
document.title = DreamConfig.document_visible_title || originTitle
DreamConfig.document_visible_title && (timer = setTimeout(function () {
document.title = originTitle
}, 2000))
}
})
},
/** 初始化轮播 **/
initCarousel() {
window.Swiper && new Swiper('.swiper', {
loop: true,
parallax: true,
effect: 'slide',
spaceBetween: 10,
speed: 600,
autoplay: {
delay: 3000,
disableOnInteraction: false,
pauseOnMouseEnter: true,
},
pagination: {
el: '.swiper-pagination',
clickable: true,
},
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
})
},
/* 个人信息界面打印彩字 */
sparkInput() {
const sparkInputContent = DreamConfig.spark_input_content && DreamConfig.spark_input_content.filter(s => s.length > 0)
if (sparkInputContent && sparkInputContent.length > 0) {
Utils.cachedScript(`${DreamConfig.theme_base}/source/js/spark-input.min.js?mew=${DreamConfig.theme_version}`, function () {
$('.spark-input').each((index, domEle) => sparkInput(domEle, sparkInputContent))
})
}
},
/* 恋爱墙倒计时 */
loveTime() {
let $elem = $('.love .love-time')
if ($elem.length === 0) return
let loveTime = $elem.attr('data-time')
if (!/^\d{4}\/\d{2}\/\d{2} \d{2}:\d{2}:\d{2}$/.test(loveTime)) {
$elem.html(loveTime)
return
}
const now = new Date()
const grt = new Date(loveTime)
setInterval(function () {
now.setTime(now.getTime() + 1000)
let difference = parseInt((now - grt) / 1000)
let seconds = difference % 60
difference = parseInt(difference / 60)
let minutes = difference % 60
difference = parseInt(difference / 60)
let hours = difference % 24
let days = parseInt(difference / 24)
let year = 0
let grtYear = grt.getFullYear()
let nowYear = now.getFullYear()
while (grtYear < nowYear) {
if ((grtYear % 4 === 0 && grtYear % 100 !== 0) || grtYear % 400 === 0) {
// 闰年366天
if (days < 366) break
days -= 366
year += 1
grtYear += 1
} else {
// 平年365天
if (days < 365) break
days -= 365
year += 1
grtYear += 1
}
}
if (year !== 0) {
$elem.html(`${year} 年 ${days} 天 ${hours} 时 ${minutes} 分 ${seconds} 秒`)
} else {
$elem.html(`${days} 天 ${hours} 时 ${minutes} 分 ${seconds} 秒`)
}
}, 1000)
},
/* 激活建站倒计时功能 */
websiteTime() {
if (!DreamConfig.website_time) {
return
}
const websiteDate = document.getElementById('websiteDate')
if (!/^\d{4}\/\d{2}\/\d{2} \d{2}:\d{2}:\d{2}$/.test(DreamConfig.website_time)) {
websiteDate.innerText = DreamConfig.website_time
return
}
const now = new Date()
const grt = new Date(DreamConfig.website_time)
setInterval(function () {
now.setTime(now.getTime() + 1000)
let difference = parseInt((now - grt) / 1000)
let seconds = difference % 60
if (String(seconds).length === 1) {
seconds = '0' + seconds
}
difference = parseInt(difference / 60)
let minutes = difference % 60
if (String(minutes).length === 1) {
minutes = '0' + minutes
}
difference = parseInt(difference / 60)
let hours = difference % 24
if (String(hours).length === 1) {
hours = '0' + hours
}
let days = parseInt(difference / 24)
websiteDate.innerHTML = `建站${days}天${hours}时${minutes}分${seconds}秒`
}, 1000)
},
/* 初始化特效,只需要初始化一次,移动端设备不初始化 */
initEffects() {
if (Utils.isMobile()) return
DreamConfig.cursor_move && Utils.cachedScript(`${DreamConfig.theme_base}/source/js/cursor/move/${DreamConfig.cursor_move}.min.js?mew=${DreamConfig.theme_version}`)
DreamConfig.cursor_click && Utils.cachedScript(`${DreamConfig.theme_base}/source/js/cursor/click/${DreamConfig.cursor_click}.min.js?mew=${DreamConfig.theme_version}`)
DreamConfig.enable_live2d && Utils.cachedScript(`${DreamConfig.theme_base}/source/js/autoload.min.js?mew=${DreamConfig.theme_version}`)
DreamConfig.effects_sakura_mode && Utils.cachedScript(`${DreamConfig.theme_base}/source/js/effects/sakura.min.js?mew=${DreamConfig.theme_version}`)
DreamConfig.effects_universe_mode && Utils.cachedScript(`${DreamConfig.theme_base}/source/js/effects/universe.min.js?mew=${DreamConfig.theme_version}`)
DreamConfig.effects_circle_magic_mode && Utils.cachedScript(`${DreamConfig.theme_base}/source/js/effects/circleMagic.min.js?mew=${DreamConfig.theme_version}`)
},
/* 加载主动推送、统计脚本等参数 */
loadMaintain() {
DreamConfig.enable_baidu_push && Utils.baiduPush()
DreamConfig.enable_toutiao_push && Utils.toutiaoPush()
},
/* 显示主题版本信息 */
showThemeVersion() {
window.logger(`%c页面加载耗时:${Math.round(performance.now())}ms | Theme By Dream ${DreamConfig.theme_version}`,
'color:#fff; background: linear-gradient(270deg, #986fee, #8695e6, #68b7dd, #18d7d3); padding: 8px 15px; border-radius: 0 15px 0 15px')
}
}
window.commonContext = commonContext
!(function () {
const loads = ['initCarousel', 'sparkInput', 'websiteTime']
const omits = ['initEffects', 'loadMaintain', 'showThemeVersion']
Object.keys(commonContext).forEach(
(c) => !loads.includes(c) && !omits.includes(c) && commonContext[c]()
)
// 当前html加载完执行
document.addEventListener('DOMContentLoaded', function () {
$('html').addClass('loaded')
loads.forEach((c) => commonContext[c] && commonContext[c]())
})
// 所有内容加载完执行
window.addEventListener('load', function () {
omits.forEach((c) => commonContext[c] && commonContext[c]())
$('html').addClass('ready')
})
})()