$(function () { const isSnackbar = GLOBAL_CONFIG.Snackbar !== undefined const isTocContent = $('#sidebar .sidebar-toc__content').children().length > 0 const $pageHead = $('#page-header') const $rightside = $('#rightside') const $body = $('body') /** * 當menu過多時,自動適配,避免UI錯亂 */ const searchWidth = $('#search_button').outerWidth() !== undefined ? $('#search_button').outerWidth() : 0 const blogNameWidth = $('#blog_name').width() var mw = 0 var $menusItem = $pageHead.find('.menus_item') for (var i = 0; i < $menusItem.length; i++) { mw = mw + $menusItem.eq(i).outerWidth() } /** * 傳入 1 sidebar打開時 * 傳入 2 正常狀態下 * 傳入 3 resize時使用 */ function isAdjust (n) { var t if (n === 1) { t = blogNameWidth + searchWidth + mw > $pageHead.width() - 300 } else if (n === 2) { t = blogNameWidth + searchWidth + mw > $pageHead.width() } if (t) headerAdjust() else headerAdjustBack() } // 初始化header function initAjust () { if (window.innerWidth < 768) headerAdjust() else isAdjust(2) } initAjust() function headerAdjust () { $pageHead.find('.toggle-menu').addClass('is_visible') $pageHead.find('.menus').addClass('is_invisible') $pageHead.find('#search_button span').addClass('is_invisible') } function headerAdjustBack () { $pageHead.find('.toggle-menu').removeClass('is_visible') $pageHead.find('.menus').removeClass('is_invisible') $pageHead.find('#search_button span').removeClass('is_invisible') } $(window).on('resize', function () { if (!$pageHead.hasClass('open-sidebar')) { initAjust() } }) /** * windows時 設置主頁top_img 為 fixed */ if (GLOBAL_CONFIG_SITE.isHome) { var isSafari = /Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent) if (!isSafari && isDesktop()) { $('#nav').css('background-attachment', 'fixed') } } /** * 進入post頁sidebar處理 */ var isSidebarOpen = $('#toggle-sidebar').hasClass('on') && isTocContent var isPcSidebarOpen = false if (window.innerWidth > 1024 && isSidebarOpen) { setTimeout(function () { openSidebar() }, 400) } // 當toc爲空時,隱藏toc按鈕 if (isTocContent) { $('#toggle-sidebar').css('opacity', '1') } else { $('#toggle-sidebar').css('display', 'none') $('#mobile-toc-button').css('display', 'none') } /** * 點擊左下角箭頭,顯示sidebar */ function closeSidebar () { isPcSidebarOpen = false $pageHead.removeClass('open-sidebar') $('#sidebar').removeClass('tocOpenPc') $('#body-wrap').animate({ paddingLeft: 0 }, 400) $('#sidebar').animate({ left: '-300px' }, 400) $('#toggle-sidebar').css({ transform: 'rotateZ(0deg)', color: '#1F2D3D', opacity: '1' }) setTimeout(function () { isAdjust(2) }, 400) } function openSidebar () { isPcSidebarOpen = true $pageHead.addClass('open-sidebar') $('#sidebar').addClass('tocOpenPc') $('#body-wrap').animate({ paddingLeft: 300 }, 400) $('#sidebar').animate({ left: 0 }, 400) $('#toggle-sidebar').css({ transform: 'rotateZ(180deg)', color: '#99a9bf', opacity: '1' }) var isAdjustTimeCount = window.setInterval(function () { isAdjust(1) }, 100) setTimeout(function () { clearInterval(isAdjustTimeCount) }, 400) } $('#toggle-sidebar').on('click', function () { var isOpen = $(this).hasClass('on') isOpen ? $(this).removeClass('on') : $(this).addClass('on') if (isOpen) { closeSidebar() } else { openSidebar() } }) /** * 手機menu和toc按鈕點擊 * 顯示menu和toc的sidebar */ var $toggleMenu = $('.toggle-menu') var $mobileSidevarMenus = $('#mobile-sidebar-menus') var $mobileTocButton = $('#mobile-toc-button') var $menuMask = $('#menu_mask') function openMobileSidebar (name) { sidebarPaddingR() $('body').css('overflow', 'hidden') $menuMask.fadeIn() if (name === 'menu') { $toggleMenu.removeClass('close').addClass('open') $mobileSidevarMenus.css('transform', 'translate3d(-100%,0,0)') var $mobileSidevarMenusChild = $mobileSidevarMenus.children() for (i = 0; i <= $mobileSidevarMenusChild.length; i++) { const duration = i / 5 + 0.2 $mobileSidevarMenusChild.eq(i).css('animation', 'sidebarItem ' + duration + 's') } } if (name === 'toc') { $mobileTocButton.removeClass('close').addClass('open') $('#sidebar').addClass('tocOpenMobile') $('#sidebar').css({ transform: 'translate3d(-100%,0,0)', left: '' }) } } function closeMobileSidebar (name) { $('body').css({ overflow: '', 'padding-right': '' }) $menuMask.fadeOut() if (name === 'menu') { $toggleMenu.removeClass('open').addClass('close') $mobileSidevarMenus.css('transform', '') $('#mobile-sidebar-menus > div,#mobile-sidebar-menus > hr').css('animation', '') } if (name === 'toc') { $mobileTocButton.removeClass('open').addClass('close') $('#sidebar').removeClass('tocOpenMobile') $('#sidebar').css({ transform: '' }) } } $toggleMenu.on('click', function () { openMobileSidebar('menu') }) $mobileTocButton.on('click', function () { openMobileSidebar('toc') }) $menuMask.on('click touchstart', function (e) { if ($toggleMenu.hasClass('open')) { closeMobileSidebar('menu') } if ($mobileTocButton.hasClass('open')) { closeMobileSidebar('toc') } }) $(window).on('resize', function (e) { if (!$toggleMenu.is(':visible')) { if ($toggleMenu.hasClass('open')) closeMobileSidebar('menu') } }) const mql = window.matchMedia('(max-width: 1024px)') mql.addListener(function (ev) { if (ev.matches) { if (isPcSidebarOpen === true) closeSidebar() } else { if ($('#toggle-sidebar').hasClass('on') && isTocContent) openSidebar() if ($mobileTocButton.hasClass('open')) closeMobileSidebar('toc') } }) /** * 首頁top_img底下的箭頭 */ $('#scroll_down').on('click', function () { scrollTo('#content-inner') }) /** * BOOKMARK 書簽 */ $('#bookmark-it').on('click', function () { if (window.sidebar && window.sidebar.addPanel) { // Mozilla Firefox Bookmark window.sidebar.addPanel(document.title, window.location.href, '') } else if (window.external && ('AddFavorite' in window.external)) { // IE Favorite window.external.AddFavorite(location.href, document.title) } else if (window.opera && window.print) { // Opera Hotlist this.title = document.title return true } else { // webkit - safari/chrome if (isSnackbar) { var bookmarkText = GLOBAL_CONFIG.Snackbar.bookmark.message_prev + ' ' + (navigator.userAgent.toLowerCase().indexOf('mac') !== -1 ? 'Command/Cmd' : 'CTRL') + '+ D ' + GLOBAL_CONFIG.Snackbar.bookmark.message_next + '.' snackbarShow(bookmarkText) } else { alert(GLOBAL_CONFIG.bookmark.message_prev + ' ' + (navigator.userAgent.toLowerCase().indexOf('mac') !== -1 ? 'Command/Cmd' : 'CTRL') + '+ D ' + GLOBAL_CONFIG.bookmark.message_next + '.') } } }) /** * 代碼 */ const isHighlightCopy = GLOBAL_CONFIG.highlightCopy const isHighlightLang = GLOBAL_CONFIG.highlightLang const isHighlightShrink = GLOBAL_CONFIG.highlightShrink const $figureHighlight = $('figure.highlight') if (isHighlightCopy || isHighlightLang || isHighlightShrink !== 'none') { $figureHighlight.wrap('
').before('
') } /** * 代碼收縮 */ const $highlightTools = $('.highlight-tools') if (isHighlightShrink === true) { $highlightTools.append('') } else if (isHighlightShrink === false) { $highlightTools.append('') } $(document).on('click', '.highlight-tools >.code-expand', function () { var $table = $(this).parent().next() if ($(this).hasClass('code-closed')) { $table.css('display', '') $(this).removeClass('code-closed') } else { $table.css('display', 'none') $(this).addClass('code-closed') } }) /** * 代碼語言 */ if (isHighlightLang) { var langNameIndex, langName $figureHighlight.each(function () { langNameIndex = langName = $(this).attr('class').split(' ')[1] if (langNameIndex === 'plain') langName = 'Code' $(this).prev().append('
' + langName + '
') }) } /** * 代碼copy * copy function */ if (isHighlightCopy) { $highlightTools.append('
') var copy = function (text, ctx) { if (document.queryCommandSupported && document.queryCommandSupported('copy')) { try { document.execCommand('copy') // Security exception may be thrown by some browsers. if (isSnackbar) { snackbarShow(GLOBAL_CONFIG.copy.success) } else { $(ctx).prev('.copy-notice') .text(GLOBAL_CONFIG.copy.success) .animate({ opacity: 1, right: 30 }, 450, function () { setTimeout(function () { $(ctx).prev('.copy-notice').animate({ opacity: 0, right: 0 }, 650) }, 400) }) } } catch (ex) { if (isSnackbar) { snackbarShow(GLOBAL_CONFIG.copy.success) } else { $(ctx).prev('.copy-notice') .text(GLOBAL_CONFIG.copy.error) .animate({ opacity: 1, right: 30 }, 650, function () { setTimeout(function () { $(ctx).prev('.copy-notice').animate({ opacity: 0, right: 0 }, 650) }, 400) }) return false } } } else { if (isSnackbar) { snackbarShow(GLOBAL_CONFIG.copy.noSupport) } else { $(ctx).prev('.copy-notice').text(GLOBAL_CONFIG.copy.noSupport) } } } // click events $(document).on('click', '.highlight-tools>.fa-clipboard', function () { var selection = window.getSelection() var range = document.createRange() range.selectNodeContents($(this).parent().next().find('.code pre')[0]) selection.removeAllRanges() selection.addRange(range) var text = selection.toString() copy(text, this) selection.removeAllRanges() }) } /** * justified-gallery 圖庫排版 */ var $justifiedGallery = $('.justified-gallery') if ($justifiedGallery.length) { var $imgList = $justifiedGallery.find('img') $imgList.unwrap() if ($imgList.length) { $imgList.each(function (i, o) { if ($(o).attr('data-src')) $(o).attr('src', $(o).attr('data-src')) $(o).wrap('
') }) } $('head').append('') loadScript('https://cdn.jsdelivr.net/npm/justifiedGallery/dist/js/jquery.justifiedGallery.min.js', function () { $justifiedGallery.not($('.hide-content .justified-gallery')).justifiedGallery({ rowHeight: 220, margins: 4 }) }) } /** * fancybox和 mediumZoom */ var isMediumZoom = GLOBAL_CONFIG.medium_zoom var isFancybox = GLOBAL_CONFIG.fancybox if (isFancybox) { var images = $('#article-container img:not(.gallery-group-img)').not($('a>img')) images.each(function (i, o) { var lazyloadSrc = $(o).attr('data-src') ? $(o).attr('data-src') : $(o).attr('src') $(o).wrap( '' ) }) $().fancybox({ selector: '[data-fancybox]', loop: true, transitionEffect: 'slide', protect: true, buttons: ['slideShow', 'fullScreen', 'thumbs', 'close'] }) } else if (isMediumZoom) { const zoom = mediumZoom(document.querySelectorAll('#article-container :not(a)>img')) zoom.on('open', function (event) { const photoBg = $(document.documentElement).attr('data-theme') === 'dark' ? '#121212' : '#fff' zoom.update({ background: photoBg }) }) } // 點擊toc,收起sidebar // $('.toc-link').on('click', function () { // closeMobileSidebar('toc') // }) var initTop = 0 $(window).scroll(function (event) { var currentTop = $(this).scrollTop() var isUp = scrollDirection(currentTop) if (currentTop > 56) { if (isUp) { if ($pageHead.hasClass('visible')) $pageHead.removeClass('visible') } else { if (!$pageHead.hasClass('visible')) $pageHead.addClass('visible') } $pageHead.addClass('fixed') if ($rightside.css('opacity') === '0') { $rightside.css({ opacity: '1', transform: 'translateX(-38px)' }) } } else { if (currentTop === 0) { $pageHead.removeClass('fixed').removeClass('visible') } $rightside.css({ opacity: '', transform: '' }) } }) // find the scroll direction function scrollDirection (currentTop) { var result = currentTop > initTop // true is down & false is up initTop = currentTop return result } /** * 點擊滾回頂部 */ $('#go-up').on('click', function () { scrollTo('body') }) /** * toc */ if (GLOBAL_CONFIG_SITE.isPost && isTocContent) { $('.toc-child').hide() // main of scroll $(window).scroll(throttle(function (event) { var currentTop = $(this).scrollTop() scrollPercent(currentTop) findHeadPosition(currentTop) autoScrollToc(currentTop) }, 100)) // scroll $('.toc-link').on('click', function (e) { if (window.innerWidth <= 1024) { closeMobileSidebar('toc') } else { e.preventDefault() scrollTo($(this).attr('href')) } }) // expand toc-item var expandToc = function ($item) { if ($item.is(':visible')) { return } $item.fadeIn(400) } var scrollPercent = function (currentTop) { var docHeight = $('#article-container').height() var winHeight = $(window).height() var contentMath = (docHeight > winHeight) ? (docHeight - winHeight) : ($(document).height() - winHeight) var scrollPercent = (currentTop) / (contentMath) var scrollPercentRounded = Math.round(scrollPercent * 100) var percentage = (scrollPercentRounded > 100) ? 100 : (scrollPercentRounded <= 0) ? 0 : scrollPercentRounded $('.progress-num').text(percentage) $('.sidebar-toc__progress-bar').animate({ width: percentage + '%' }, 100) } var updateAnchor = function (anchor) { if (window.history.replaceState && anchor !== window.location.hash) { window.history.replaceState(undefined, undefined, anchor) } } // find head position & add active class // DOM Hierarchy: // ol.toc > (li.toc-item, ...) // li.toc-item > (a.toc-link, ol.toc-child > (li.toc-item, ...)) var 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 ($('.toc-link').length === 0) { return false } var list = $('#article-container').find('h1,h2,h3,h4,h5,h6') var currentId = '' list.each(function () { var head = $(this) if (top > head.offset().top - 25) { currentId = '#' + $(this).attr('id') } }) if (currentId === '') { $('.toc-link').removeClass('active') $('.toc-child').hide() } var currentActive = $('.toc-link.active') if (currentId && currentActive.attr('href') !== currentId) { updateAnchor(currentId) $('.toc-link').removeClass('active') var _this = $('.toc-link[href="' + currentId + '"]') _this.addClass('active') var 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 var 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() } } var autoScrollToc = function (currentTop) { if ($('.toc-link').hasClass('active')) { var activePosition = $('.active').offset().top var sidebarScrolltop = $('#sidebar .sidebar-toc__content').scrollTop() if (activePosition > (currentTop + $(window).height() - 100)) { $('#sidebar .sidebar-toc__content').scrollTop(sidebarScrolltop + 100) } if (activePosition < currentTop + 100) { $('#sidebar .sidebar-toc__content').scrollTop(sidebarScrolltop - 100) } } } } /** * 閲讀模式 */ $('#readmode').click(function () { $('body').toggleClass('read-mode') }) /** * 字體調整 */ $('#font_plus').click(function () { $body.css('font-size', parseFloat($body.css('font-size')) + 1) }) $('#font_minus').click(function () { $body.css('font-size', parseFloat($body.css('font-size')) - 1) }) /** * menu * 側邊欄sub-menu 展開/收縮 * 解決menus在觸摸屏下,滑動屏幕menus_item_child不消失的問題(手機hover的bug) */ $('#mobile-sidebar-menus .menus-expand').on('click', function () { if ($(this).hasClass('menus-closed')) { $(this).parents('.menus_item').find('.menus_item_child').slideDown() $(this).removeClass('menus-closed') } else { $(this).parents('.menus_item').find('.menus_item_child').slideUp() $(this).addClass('menus-closed') } }) $(window).on('touchmove', function (e) { var $menusChild = $('#page-header .menus_item_child') if ($menusChild.is(':visible')) { $menusChild.css('display', 'none') } }) /** * rightside 點擊設置 按鈕 展開 */ $('#rightside_config').on('click', function () { if ($('#rightside-config-hide').hasClass('rightside-in')) { $('#rightside-config-hide').removeClass('rightside-in').addClass('rightside-out') } else { $('#rightside-config-hide').removeClass('rightside-out').addClass('rightside-in') } }) /** * 複製時加上版權信息 */ var copyright = GLOBAL_CONFIG.copyright if (copyright !== undefined) { document.body.oncopy = function (event) { event.preventDefault() let textFont; const copyFont = window.getSelection(0).toString() if (copyFont.length > 45) { textFont = copyFont + '\n' + '\n' + '\n' + copyright.languages.author + '\n' + copyright.languages.link + '\n' + copyright.languages.source + '\n' + copyright.languages.info } else { textFont = copyFont } if (event.clipboardData) { return event.clipboardData.setData('text', textFont) } else { // 兼容IE return window.clipboardData.setData('text', textFont) } } } /** * Darkmode */ var isFontAwesomeV5 = GLOBAL_CONFIG.isFontAwesomeV5 var $darkModeButtom = $('#darkmode') if (typeof autoChangeMode !== 'undefined') { if (Cookies.get('theme') === 'dark') changeLightIcon() else changeDarkIcon() } function changeLightIcon () { isFontAwesomeV5 ? $darkModeButtom.removeClass('fa-moon').addClass('fa-sun') : $darkModeButtom.removeClass('fa-moon-o').addClass('fa-sun-o') } function changeDarkIcon () { isFontAwesomeV5 ? $darkModeButtom.removeClass('fa-sun').addClass('fa-moon') : $darkModeButtom.removeClass('fa-sun-o').addClass('fa-moon-o') } function switchReadMode () { var nowMode = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light' if (nowMode === 'light') { changeLightIcon() activateDarkMode() Cookies.set('theme', 'dark', { expires: 2 }) if (isSnackbar) snackbarShow(GLOBAL_CONFIG.Snackbar.day_to_night) } else { changeDarkIcon() activateLightMode() Cookies.set('theme', 'light', { expires: 2 }) if (isSnackbar) snackbarShow(GLOBAL_CONFIG.Snackbar.night_to_day) } } $darkModeButtom.click(function () { switchReadMode() try { utterancesTheme() } catch (e) { return false } }) /** * 網頁運行時間 */ if (GLOBAL_CONFIG.runtime) { // get user config var $runtimeCount = $('#webinfo-runtime-count') var startDate = $runtimeCount.attr('start_date') var showDateTime = function () { var BirthDay = new Date(startDate) var today = new Date() var timeold = (today.getTime() - BirthDay.getTime()) var daysold = Math.floor(timeold / (24 * 60 * 60 * 1000)) $runtimeCount.text(daysold + ' ' + GLOBAL_CONFIG.runtime_unit) } var interval showDateTime() clearInterval(interval) interval = setInterval(showDateTime, 10000) } if (GLOBAL_CONFIG.baiduPush) { (function () { var bp = document.createElement('script') var curProtocol = window.location.protocol.split(':')[0] if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js' } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js' } var s = document.getElementsByTagName('script')[0] s.parentNode.insertBefore(bp, s) })() } /** * tag-hide */ var $hideInline = $('.hide-button') $hideInline.on('click', function (e) { e.preventDefault() $(this).hide() var $hideContent = $(this).next('.hide-content') $hideContent.show() $hideContent.find('.justified-gallery').justifiedGallery({ rowHeight: 220, margins: 4 }) }) })