1document.addEventListener('DOMContentLoaded', function () { 2 let blogNameWidth, menusWidth, searchWidth, $nav 3 let mobileSidebarOpen = false 4 5 const adjustMenu = (init) => { 6 if (init) { 7 blogNameWidth = document.getElementById('site-name').offsetWidth 8 const $menusEle = document.querySelectorAll('#menus .menus_item') 9 menusWidth = 0 10 $menusEle.length && $menusEle.forEach(i => { menusWidth += i.offsetWidth }) 11 const $searchEle = document.querySelector('#search-button') 12 searchWidth = $searchEle ? $searchEle.offsetWidth : 0 13 $nav = document.getElementById('nav') 14 } 15 16 let hideMenuIndex = '' 17 if (window.innerWidth < 768) hideMenuIndex = true 18 else hideMenuIndex = blogNameWidth + menusWidth + searchWidth > $nav.offsetWidth - 120 19 20 if (hideMenuIndex) { 21 $nav.classList.add('hide-menu') 22 } else { 23 $nav.classList.remove('hide-menu') 24 } 25 } 26 27 // åå§åheader 28 const initAdjust = () => { 29 adjustMenu(true) 30 $nav.classList.add('show') 31 } 32 33 // sidebar menus 34 const sidebarFn = { 35 open: () => { 36 btf.sidebarPaddingR() 37 document.body.style.overflow = 'hidden' 38 btf.animateIn(document.getElementById('menu-mask'), 'to_show 0.5s') 39 document.getElementById('sidebar-menus').classList.add('open') 40 mobileSidebarOpen = true 41 }, 42 close: () => { 43 const $body = document.body 44 $body.style.overflow = '' 45 $body.style.paddingRight = '' 46 btf.animateOut(document.getElementById('menu-mask'), 'to_hide 0.5s') 47 document.getElementById('sidebar-menus').classList.remove('open') 48 mobileSidebarOpen = false 49 } 50 } 51 52 /** 53 * é¦é top_imgåºä¸çç®é 54 */ 55 const scrollDownInIndex = () => { 56 const $scrollDownEle = document.getElementById('scroll-down') 57 $scrollDownEle && $scrollDownEle.addEventListener('click', function () { 58 btf.scrollToDest(document.getElementById('content-inner').offsetTop, 300) 59 }) 60 } 61 62 /** 63 * 代碼 64 * åªé©ç¨æ¼Hexoé»èªç代碼渲æ 65 */ 66 const addHighlightTool = function () { 67 const highLight = GLOBAL_CONFIG.highlight 68 if (!highLight) return 69 70 const isHighlightCopy = highLight.highlightCopy 71 const isHighlightLang = highLight.highlightLang 72 const isHighlightShrink = GLOBAL_CONFIG_SITE.isHighlightShrink 73 const highlightHeightLimit = highLight.highlightHeightLimit 74 const isShowTool = isHighlightCopy || isHighlightLang || isHighlightShrink !== undefined 75 const $figureHighlight = highLight.plugin === 'highlighjs' ? document.querySelectorAll('figure.highlight') : document.querySelectorAll('pre[class*="language-"]') 76 77 if (!((isShowTool || highlightHeightLimit) && $figureHighlight.length)) return 78 79 const isPrismjs = highLight.plugin === 'prismjs' 80 81 let highlightShrinkEle = '' 82 let highlightCopyEle = '' 83 const highlightShrinkClass = isHighlightShrink === true ? 'closed' : '' 84 85 if (isHighlightShrink !== undefined) { 86 highlightShrinkEle = `<i class="fas fa-angle-down expand ${highlightShrinkClass}"></i>` 87 } 88 89 if (isHighlightCopy) { 90 highlightCopyEle = '<div class="copy-notice"></div><i class="fas fa-paste copy-button"></i>' 91 } 92 93 const copy = (text, ctx) => { 94 if (document.queryCommandSupported && document.queryCommandSupported('copy')) { 95 document.execCommand('copy') 96 if (GLOBAL_CONFIG.Snackbar !== undefined) { 97 btf.snackbarShow(GLOBAL_CONFIG.copy.success) 98 } else { 99 const prevEle = ctx.previousElementSibling 100 prevEle.innerText = GLOBAL_CONFIG.copy.success 101 prevEle.style.opacity = 1 102 setTimeout(() => { prevEle.style.opacity = 0 }, 700) 103 } 104 } else { 105 if (GLOBAL_CONFIG.Snackbar !== undefined) { 106 btf.snackbarShow(GLOBAL_CONFIG.copy.noSupport) 107 } else { 108 ctx.previousElementSibling.innerText = GLOBAL_CONFIG.copy.noSupport 109 } 110 } 111 } 112 113 // click events 114 const highlightCopyFn = (ele) => { 115 const $buttonParent = ele.parentNode 116 $buttonParent.classList.add('copy-true') 117 const selection = window.getSelection() 118 const range = document.createRange()
119 if (isPrismjs) range.selectNodeContents($buttonParent.querySelectorAll('pre code')[0]) 120 else range.selectNodeContents($buttonParent.querySelectorAll('table .code pre')[0]) 121 selection.removeAllRanges() 122 selection.addRange(range) 123 const text = selection.toString() 124 copy(text, ele.lastChild) 125 selection.removeAllRanges() 126 $buttonParent.classList.remove('copy-true') 127 } 128 129 const highlightShrinkFn = (ele) => { 130 const $nextEle = [...ele.parentNode.children].slice(1) 131 ele.firstChild.classList.toggle('closed') 132 if (btf.isHidden($nextEle[$nextEle.length - 1])) { 133 $nextEle.forEach(e => { e.style.display = 'block' }) 134 } else { 135 $nextEle.forEach(e => { e.style.display = 'none' }) 136 } 137 } 138 139 const highlightToolsFn = function (e) { 140 const $target = e.target.classList 141 if ($target.contains('expand')) highlightShrinkFn(this) 142 else if ($target.contains('copy-button')) highlightCopyFn(this) 143 } 144 145 const expandCode = function () { 146 this.classList.toggle('expand-done') 147 } 148 149 function createEle (lang, item, service) { 150 const fragment = document.createDocumentFragment() 151 152 if (isShowTool) { 153 const hlTools = document.createElement('div') 154 hlTools.className = `highlight-tools ${highlightShrinkClass}` 155 hlTools.innerHTML = highlightShrinkEle + lang + highlightCopyEle 156 hlTools.addEventListener('click', highlightToolsFn) 157 fragment.appendChild(hlTools) 158 } 159 160 if (highlightHeightLimit && item.offsetHeight > highlightHeightLimit + 30) { 161 const ele = document.createElement('div') 162 ele.className = 'code-expand-btn' 163 ele.innerHTML = '<i class="fas fa-angle-double-down"></i>' 164 ele.addEventListener('click', expandCode) 165 fragment.appendChild(ele) 166 } 167 168 if (service === 'hl') { 169 item.insertBefore(fragment, item.firstChild) 170 } else { 171 item.parentNode.insertBefore(fragment, item) 172 } 173 } 174 175 if (isHighlightLang) { 176 if (isPrismjs) { 177 $figureHighlight.forEach(function (item) { 178 const langName = item.getAttribute('data-language') ? item.getAttribute('data-language') : 'Code' 179 const highlightLangEle = `<div class="code-lang">${langName}</div>` 180 btf.wrap(item, 'figure', { class: 'highlight' }) 181 createEle(highlightLangEle, item) 182 }) 183 } else { 184 $figureHighlight.forEach(function (item) { 185 let langName = item.getAttribute('class').split(' ')[1] 186 if (langName === 'plain' || langName === undefined) langName = 'Code' 187 const highlightLangEle = `<div class="code-lang">${langName}</div>` 188 createEle(highlightLangEle, item, 'hl') 189 }) 190 } 191 } else { 192 if (isPrismjs) { 193 $figureHighlight.forEach(function (item) { 194 btf.wrap(item, 'figure', { class: 'highlight' }) 195 createEle('', item) 196 }) 197 } else { 198 $figureHighlight.forEach(function (item) { 199 createEle('', item, 'hl') 200 }) 201 } 202 } 203 } 204 205 /** 206 * PhotoFigcaption 207 */ 208 function addPhotoFigcaption () { 209 document.querySelectorAll('#article-container img').forEach(function (item) { 210 const parentEle = item.parentNode 211 const altValue = item.title || item.alt 212 if (altValue && !parentEle.parentNode.classList.contains('justified-gallery')) { 213 const ele = document.createElement('div') 214 ele.className = 'img-alt is-center' 215 ele.textContent = altValue 216 parentEle.insertBefore(ele, item.nextSibling) 217 } 218 }) 219 } 220 221 /** 222 * Lightbox 223 */ 224 const runLightbox = () => { 225 btf.loadLightbox(document.querySelectorAll('#article-container img:not(.no-lightbox)')) 226 } 227 228 /** 229 * justified-gallery å庫æç 230 */ 231 const runJustifiedGallery = function (ele) { 232 ele.forEach(item => { 233 const $imgList = item.querySelectorAll('img') 234 235 $imgList.forEach(i => { 236 const dataLazySrc = i.getAttribute('data-lazy-src') 237 if (dataLazySrc) i.src = dataLazySrc 238 btf.wrap(i, 'div', { class: 'fj-gallery-item' }) 239 }) 240 }) 241 242 if (window.fjGallery) { 243 setTimeout(() => { btf.initJustifiedGallery(ele) }, 100) 244 return 245 } 246 247 const newEle = document.createElement('link') 248 newEle.rel = 'stylesheet' 249 newEle.href = GLOBAL_CONFIG.source.justifiedGallery.css 250 document.body.appendChild(newEle) 251 getScript(`${GLOBAL_CONFIG.source.justifiedGallery.js}`).then(() => { btf.initJustifiedGallery(ele) }) 252 } 253 254 /** 255 * 滾åèç 256 */ 257 const scrollFn = function () { 258 const $rightside = document.getElementById('rightside') 259 const innerHeight = window.innerHeight + 56 260 261 // ç¶æ»¾åæ¢å°äº 56 çæå
262 if (document.body.scrollHeight <= innerHeight) { 263 $rightside.style.cssText = 'opacity: 1; transform: translateX(-58px)' 264 return 265 } 266 267 // find the scroll direction 268 function scrollDirection (currentTop) { 269 const result = currentTop > initTop // true is down & false is up 270 initTop = currentTop 271 return result 272 } 273 274 let initTop = 0 275 let isChatShow = true 276 const $header = document.getElementById('page-header') 277 const isChatBtnHide = typeof chatBtnHide === 'function' 278 const isChatBtnShow = typeof chatBtnShow === 'function' 279 280 window.scrollCollect = () => { 281 return btf.throttle(function (e) { 282 const currentTop = window.scrollY || document.documentElement.scrollTop 283 const isDown = scrollDirection(currentTop) 284 if (currentTop > 56) { 285 if (isDown) { 286 if ($header.classList.contains('nav-visible')) $header.classList.remove('nav-visible') 287 if (isChatBtnShow && isChatShow === true) { 288 chatBtnHide() 289 isChatShow = false 290 } 291 } else { 292 if (!$header.classList.contains('nav-visible')) $header.classList.add('nav-visible') 293 if (isChatBtnHide && isChatShow === false) { 294 chatBtnShow() 295 isChatShow = true 296 } 297 } 298 $header.classList.add('nav-fixed') 299 if (window.getComputedStyle($rightside).getPropertyValue('opacity') === '0') { 300 $rightside.style.cssText = 'opacity: 0.8; transform: translateX(-58px)' 301 } 302 } else { 303 if (currentTop === 0) { 304 $header.classList.remove('nav-fixed', 'nav-visible') 305 } 306 $rightside.style.cssText = "opacity: ''; transform: ''" 307 } 308
309 if (document.body.scrollHeight <= innerHeight) { 310 $rightside.style.cssText = 'opacity: 0.8; transform: translateX(-58px)' 311 } 312 }, 200)() 313 } 314 315 window.addEventListener('scroll', scrollCollect) 316 } 317 318 /** 319 * toc,anchor 320 */ 321 const scrollFnToDo = function () { 322 const isToc = GLOBAL_CONFIG_SITE.isToc 323 const isAnchor = GLOBAL_CONFIG.isAnchor 324 const $article = document.getElementById('article-container') 325 326 if (!($article && (isToc || isAnchor))) return 327 328 let $tocLink, $cardToc, scrollPercent, autoScrollToc, isExpand 329 330 if (isToc) { 331 const $cardTocLayout = document.getElementById('card-toc') 332 $cardToc = $cardTocLayout.getElementsByClassName('toc-content')[0] 333 $tocLink = $cardToc.querySelectorAll('.toc-link') 334 const $tocPercentage = $cardTocLayout.querySelector('.toc-percentage') 335 isExpand = $cardToc.classList.contains('is-expand') 336 337 scrollPercent = currentTop => { 338 const docHeight = $article.clientHeight 339 const winHeight = document.documentElement.clientHeight 340 const headerHeight = $article.offsetTop 341 const contentMath = (docHeight > winHeight) ? (docHeight - winHeight) : (document.documentElement.scrollHeight - winHeight) 342 const scrollPercent = (currentTop - headerHeight) / (contentMath) 343 const scrollPercentRounded = Math.round(scrollPercent * 100) 344 const percentage = (scrollPercentRounded > 100) ? 100 : (scrollPercentRounded <= 0) ? 0 : scrollPercentRounded 345 $tocPercentage.textContent = percentage 346 } 347 348 window.mobileToc = { 349 open: () => { 350 $cardTocLayout.style.cssText = 'animation: toc-open .3s; opacity: 1; right: 55px' 351 }, 352 353 close: () => { 354 $cardTocLayout.style.animation = 'toc-close .2s' 355 setTimeout(() => { 356 $cardTocLayout.style.cssText = "opacity:''; animation: ''; right: ''" 357 }, 100) 358 } 359 } 360 361 // tocå ç´ é»æ 362 $cardToc.addEventListener('click', e => { 363 e.preventDefault() 364 const target = e.target.classList 365 if (target.contains('toc-content')) return 366 const $target = target.contains('toc-link') 367 ? e.target 368 : e.target.parentElement 369 btf.scrollToDest(btf.getEleTop(document.getElementById(decodeURI($target.getAttribute('href')).replace('#', ''))), 300) 370 if (window.innerWidth < 900) { 371 window.mobileToc.close() 372 } 373 }) 374 375 autoScrollToc = item => { 376 const activePosition = item.getBoundingClientRect().top 377 const sidebarScrollTop = $cardToc.scrollTop 378 if (activePosition > (document.documentElement.clientHeight - 100)) { 379 $cardToc.scrollTop = sidebarScrollTop + 150 380 } 381 if (activePosition < 100) { 382 $cardToc.scrollTop = sidebarScrollTop - 150 383 } 384 } 385 } 386 387 // find head position & add active class 388 const list = $article.querySelectorAll('h1,h2,h3,h4,h5,h6') 389 let detectItem = '' 390 const findHeadPosition = function (top) { 391 if (top === 0) { 392 return false 393 } 394 395 let currentId = '' 396 let currentIndex = '' 397 398 list.forEach(function (ele, index) { 399 if (top > btf.getEleTop(ele) - 80) { 400 const id = ele.id 401 currentId = id ? '#' + encodeURI(id) : '' 402 currentIndex = index 403 } 404 }) 405 406 if (detectItem === currentIndex) return 407 408 if (isAnchor) btf.updateAnchor(currentId) 409 410 detectItem = currentIndex 411 412 if (isToc) { 413 $cardToc.querySelectorAll('.active').forEach(i => { i.classList.remove('active') }) 414 415 if (currentId === '') { 416 return 417 } 418 419 const currentActive = $tocLink[currentIndex] 420 currentActive.classList.add('active') 421 422 setTimeout(() => { 423 autoScrollToc(currentActive) 424 }, 0) 425 426 if (isExpand) return 427 let parent = currentActive.parentNode 428 429 for (; !parent.matches('.toc'); parent = parent.parentNode) { 430 if (parent.matches('li')) parent.classList.add('active') 431 } 432 } 433 } 434 435 // main of scroll 436 window.tocScrollFn = function () { 437 return btf.throttle(function () { 438 const currentTop = window.scrollY || document.documentElement.scrollTop 439 isToc && scrollPercent(currentTop) 440 findHeadPosition(currentTop) 441 }, 100)() 442 } 443 window.addEventListener('scroll', tocScrollFn) 444 } 445 446 /** 447 * Rightside 448 */ 449 const rightSideFn = { 450 switchReadMode: () => { // read-mode 451 const $body = document.body 452 $body.classList.add('read-mode') 453 const newEle = document.createElement('button') 454 newEle.type = 'button' 455 newEle.className = 'fas fa-sign-out-alt exit-readmode' 456 $body.appendChild(newEle) 457 458 function clickFn () { 459 $body.classList.remove('read-mode') 460 newEle.remove() 461 newEle.removeEventListener('click', clickFn) 462 } 463 464 newEle.addEventListener('click', clickFn) 465 }, 466 switchDarkMode: () => { // Switch Between Light And Dark Mode 467 const nowMode = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light' 468 if (nowMode === 'light') { 469 activateDarkMode() 470 saveToLocal.set('theme', 'dark', 2) 471 GLOBAL_CONFIG.Snackbar !== undefined && btf.snackbarShow(GLOBAL_CONFIG.Snackbar.day_to_night) 472 } else { 473 activateLightMode() 474 saveToLocal.set('theme', 'light', 2) 475 GLOBAL_CONFIG.Snackbar !== undefined && btf.snackbarShow(GLOBAL_CONFIG.Snackbar.night_to_day) 476 } 477 // handle some cases 478 typeof utterancesTheme === 'function' && utterancesTheme() 479 typeof changeGiscusTheme === 'function' && changeGiscusTheme() 480 typeof FB === 'object' && window.loadFBComment() 481 window.DISQUS && document.getElementById('disqus_thread').children.length && setTimeout(() => window.disqusReset(), 200) 482 typeof runMermaid === 'function' && window.runMermaid() 483 }, 484 showOrHideBtn: (e) => { // rightside 黿è¨ç½® æé å±é 485 const rightsideHideClassList = document.getElementById('rightside-config-hide').classList 486 rightsideHideClassList.toggle('show') 487 if (e.classList.contains('show')) { 488 rightsideHideClassList.add('status') 489 setTimeout(() => { 490 rightsideHideClassList.remove('status') 491 }, 300) 492 } 493 e.classList.toggle('show') 494 }, 495 scrollToTop: () => { // Back to top 496 btf.scrollToDest(0, 500) 497 }, 498 hideAsideBtn: () => { // Hide aside 499 const $htmlDom = document.documentElement.classList 500 $htmlDom.contains('hide-aside') 501 ? saveToLocal.set('aside-status', 'show', 2) 502 : saveToLocal.set('aside-status', 'hide', 2) 503 $htmlDom.toggle('hide-aside') 504 }, 505 506 runMobileToc: () => { 507 if (window.getComputedStyle(document.getElementById('card-toc')).getPropertyValue('opacity') === '0') window.mobileToc.open() 508 else window.mobileToc.close() 509 } 510 } 511 512 document.getElementById('rightside').addEventListener('click', function (e) { 513 const $target = e.target.id ? e.target : e.target.parentNode 514 switch ($target.id) { 515 case 'go-up': 516 rightSideFn.scrollToTop() 517 break 518 case 'rightside_config': 519 rightSideFn.showOrHideBtn($target) 520 break 521 case 'mobile-toc-button': 522 rightSideFn.runMobileToc() 523 break 524 case 'readmode': 525 rightSideFn.switchReadMode() 526 break 527 case 'darkmode': 528 rightSideFn.switchDarkMode() 529 break 530 case 'hide-aside-btn': 531 rightSideFn.hideAsideBtn() 532 break 533 default: 534 break 535 } 536 }) 537 538 /** 539 * menu 540 * å´éæ¬sub-menu å±é/æ¶ç¸® 541 */
542 const clickFnOfSubMenu = () => { 543 document.querySelectorAll('#sidebar-menus .site-page.group').forEach(function (item) { 544 item.addEventListener('click', function () { 545 this.classList.toggle('hide') 546 }) 547 }) 548 } 549 550 /** 551 * è¤è£½æå ä¸çæ¬ä¿¡æ¯ 552 */ 553 const addCopyright = () => { 554 const copyright = GLOBAL_CONFIG.copyright 555 document.body.oncopy = (e) => { 556 e.preventDefault() 557 let textFont; const copyFont = window.getSelection(0).toString() 558 if (copyFont.length > copyright.limitCount) { 559 textFont = copyFont + '\n' + '\n' + '\n' + 560 copyright.languages.author + '\n' + 561 copyright.languages.link + window.location.href + '\n' + 562 copyright.languages.source + '\n' + 563 copyright.languages.info 564 } else { 565 textFont = copyFont 566 } 567 if (e.clipboardData) { 568 return e.clipboardData.setData('text', textFont) 569 } else { 570 return window.clipboardData.setData('text', textFont) 571 } 572 } 573 } 574 575 /** 576 * ç¶²é éè¡æé 577 */ 578 const addRuntime = () => { 579 const $runtimeCount = document.getElementById('runtimeshow') 580 if ($runtimeCount) { 581 const publishDate = $runtimeCount.getAttribute('data-publishDate') 582 $runtimeCount.innerText = btf.diffDate(publishDate) + ' ' + GLOBAL_CONFIG.runtime 583 } 584 } 585 586 /** 587 * æå¾ä¸æ¬¡æ´æ°æé 588 */ 589 const addLastPushDate = () => { 590 const $lastPushDateItem = document.getElementById('last-push-date') 591 if ($lastPushDateItem) { 592 const lastPushDate = $lastPushDateItem.getAttribute('data-lastPushDate') 593 $lastPushDateItem.innerText = btf.diffDate(lastPushDate, true) 594 } 595 } 596 597 /** 598 * table overflow 599 */ 600 const addTableWrap = () => { 601 const $table = document.querySelectorAll('#article-container :not(.highlight) > table, #article-container > table') 602 if ($table.length) { 603 $table.forEach(item => { 604 btf.wrap(item, 'div', { class: 'table-wrap' }) 605 }) 606 } 607 } 608 609 /** 610 * tag-hide 611 */ 612 const clickFnOfTagHide = function () { 613 const $hideInline = document.querySelectorAll('#article-container .hide-button') 614 if ($hideInline.length) { 615 $hideInline.forEach(function (item) { 616 item.addEventListener('click', function (e) { 617 const $this = this 618 $this.classList.add('open') 619 const $fjGallery = $this.nextElementSibling.querySelectorAll('.fj-gallery') 620 $fjGallery.length && btf.initJustifiedGallery($fjGallery) 621 }) 622 }) 623 } 624 } 625 626 const tabsFn = { 627 clickFnOfTabs: function () { 628 document.querySelectorAll('#article-container .tab > button').forEach(function (item) { 629 item.addEventListener('click', function (e) { 630 const $this = this 631 const $tabItem = $this.parentNode 632 633 if (!$tabItem.classList.contains('active')) { 634 const $tabContent = $tabItem.parentNode.nextElementSibling 635 const $siblings = btf.siblings($tabItem, '.active')[0] 636 $siblings && $siblings.classList.remove('active') 637 $tabItem.classList.add('active') 638 const tabId = $this.getAttribute('data-href').replace('#', '') 639 const childList = [...$tabContent.children] 640 childList.forEach(item => { 641 if (item.id === tabId) item.classList.add('active') 642 else item.classList.remove('active') 643 }) 644 const $isTabJustifiedGallery = $tabContent.querySelectorAll(`#${tabId} .fj-gallery`) 645 if ($isTabJustifiedGallery.length > 0) { 646 btf.initJustifiedGallery($isTabJustifiedGallery) 647 } 648 } 649 }) 650 }) 651 }, 652 backToTop: () => { 653 document.querySelectorAll('#article-container .tabs .tab-to-top').forEach(function (item) { 654 item.addEventListener('click', function () { 655 btf.scrollToDest(btf.getEleTop(btf.getParents(this, '.tabs')), 300) 656 }) 657 }) 658 } 659 } 660 661 const toggleCardCategory = function () { 662 const $cardCategory = document.querySelectorAll('#aside-cat-list .card-category-list-item.parent i') 663 if ($cardCategory.length) {
664 $cardCategory.forEach(function (item) { 665 item.addEventListener('click', function (e) { 666 e.preventDefault() 667 const $this = this 668 $this.classList.toggle('expand') 669 const $parentEle = $this.parentNode.nextElementSibling 670 if (btf.isHidden($parentEle)) { 671 $parentEle.style.display = 'block' 672 } else { 673 $parentEle.style.display = 'none' 674 } 675 }) 676 }) 677 } 678 } 679 680 const switchComments = function () { 681 let switchDone = false 682 const $switchBtn = document.querySelector('#comment-switch > .switch-btn') 683 $switchBtn && $switchBtn.addEventListener('click', function () { 684 this.classList.toggle('move') 685 document.querySelectorAll('#post-comment > .comment-wrap > div').forEach(function (item) { 686 if (btf.isHidden(item)) { 687 item.style.cssText = 'display: block;animation: tabshow .5s' 688 } else { 689 item.style.cssText = "display: none;animation: ''" 690 } 691 }) 692 693 if (!switchDone && typeof loadOtherComment === 'function') { 694 switchDone = true 695 loadOtherComment() 696 } 697 }) 698 } 699 700 const addPostOutdateNotice = function () { 701 const data = GLOBAL_CONFIG.noticeOutdate 702 const diffDay = btf.diffDate(GLOBAL_CONFIG_SITE.postUpdate) 703 if (diffDay >= data.limitDay) { 704 const ele = document.createElement('div') 705 ele.className = 'post-outdate-notice' 706 ele.textContent = data.messagePrev + ' ' + diffDay + ' ' + data.messageNext 707 const $targetEle = document.getElementById('article-container') 708 if (data.position === 'top') { 709 $targetEle.insertBefore(ele, $targetEle.firstChild) 710 } else { 711 $targetEle.appendChild(ele) 712 } 713 } 714 } 715 716 const lazyloadImg = () => { 717 window.lazyLoadInstance = new LazyLoad({ 718 elements_selector: 'img', 719 threshold: 0, 720 data_src: 'lazy-src' 721 }) 722 } 723 724 const relativeDate = function (selector) { 725 selector.forEach(item => { 726 const $this = item 727 const timeVal = $this.getAttribute('datetime') 728 $this.innerText = btf.diffDate(timeVal, true) 729 $this.style.display = 'inline' 730 }) 731 } 732 733 const unRefreshFn = function () { 734 window.addEventListener('resize', () => { 735 adjustMenu(false) 736 btf.isHidden(document.getElementById('toggle-menu')) && mobileSidebarOpen && sidebarFn.close() 737 }) 738 739 document.getElementById('menu-mask').addEventListener('click', e => { sidebarFn.close() }) 740 741 clickFnOfSubMenu() 742 GLOBAL_CONFIG.islazyload && lazyloadImg() 743 GLOBAL_CONFIG.copyright !== undefined && addCopyright() 744 } 745 746 window.refreshFn = function () { 747 initAdjust() 748 749 if (GLOBAL_CONFIG_SITE.isPost) { 750 GLOBAL_CONFIG.noticeOutdate !== undefined && addPostOutdateNotice() 751 GLOBAL_CONFIG.relativeDate.post && relativeDate(document.querySelectorAll('#post-meta time')) 752 } else { 753 GLOBAL_CONFIG.relativeDate.homepage && relativeDate(document.querySelectorAll('#recent-posts time')) 754 GLOBAL_CONFIG.runtime && addRuntime() 755 addLastPushDate() 756 toggleCardCategory() 757 } 758 759 scrollFnToDo() 760 GLOBAL_CONFIG_SITE.isHome && scrollDownInIndex() 761 addHighlightTool() 762 GLOBAL_CONFIG.isPhotoFigcaption && addPhotoFigcaption() 763 scrollFn() 764 765 const $jgEle = document.querySelectorAll('#article-container .fj-gallery') 766 $jgEle.length && runJustifiedGallery($jgEle) 767 768 runLightbox() 769 addTableWrap() 770 clickFnOfTagHide() 771 tabsFn.clickFnOfTabs() 772 tabsFn.backToTop() 773 switchComments() 774 document.getElementById('toggle-menu').addEventListener('click', () => { sidebarFn.open() }) 775 } 776 777 refreshFn() 778 unRefreshFn() 779})
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.