1const nav = document.querySelector('nav'); 2if (!nav.classList.contains('sakura_nav')) { 3 init_iro_nav(); 4} 5function init_iro_nav() { 6// å¯¼èªæ é¿åº¦éå¶ 7 function initNavWidth() { 8 const nav = document.querySelector('nav'); 9 const checkWidth = () => { 10 if (nav.offsetWidth > 1200) { 11 nav.style.overflowX = 'hidden'; 12 nav.style.maxWidth = '1200px'; 13 } else { 14 nav.style.overflowX = ''; 15 nav.style.maxWidth = ''; 16 } 17 }; 18 checkWidth(); 19 window.addEventListener('resize', checkWidth); 20 } 21 22 document.addEventListener('DOMContentLoaded', initNavWidth); 23 document.addEventListener('pjax:complete', initNavWidth); 24 25// å®ä¹DOMå ç´ 26const DOM = { 27 bgNext: document.getElementById("bg-next"), 28 navSearchWrapper: document.querySelector(".nav-search-wrapper"), 29 searchbox: document.querySelector(".searchbox.js-toggle-search"), 30 divider: document.querySelector(".nav-search-divider"), 31}; 32 33if (!DOM.bgNext) { 34 DOM.bgNext = document.createElement('div'); // ç»ä¸ä¸ªèæçå ç´ ï¼åé¢ä¸åä¸ä¸ªä¸ªå¤æå ç´ æ¯å¦åå¨ 35} 36 37// å®ä¹å¨ç»åæ° 38const ANIMATION = { 39 easing: "cubic-bezier(0.34, 1.56, 0.64, 1)", 40 duration: "0.6s", 41 durationMs: 600, 42}; 43 44// æ¹è¿çç¶æç®¡çå¨ 45const StateManager = { 46 init() { 47 try { 48 const currentIsHome = location.pathname === "/" || location.pathname === "/index.php"; 49 50 // 强å¶éç½®éä¸»é¡µç¶æ 51 if(!currentIsHome && sessionStorage.getItem("bgNextState")){ 52 sessionStorage.removeItem("bgNextState"); 53 } 54 55 if (sessionStorage.getItem("bgNextState")) { 56 return this.getState(); 57 } 58 const state = { 59 lastPageWasHome: false, 60 isTransitioning: false, 61 firstLoad: true, 62 initialized: false, 63 firstHomeTransition: true, // æ°å¢ï¼è¿½è¸ªç¬¬ä¸æ¬¡ä¸»é¡µè¿æ¸¡ 64 initializedOutsideHome: false // æ°å¢ï¼è¿½è¸ªæ¯å¦å¨é䏻页宿åå§å 65 }; 66 this.setState(state); 67 return state; 68 } catch (e) { 69 console.warn('StateManager initialization failed:', e); 70 return { 71 lastPageWasHome: false, 72 isTransitioning: false, 73 firstLoad: true, 74 initialized: false, 75 firstHomeTransition: true, 76 initializedOutsideHome: false 77 }; 78 } 79 }, 80 81 getState() { 82 return JSON.parse(sessionStorage.getItem("bgNextState")); 83 }, 84 85 setState(state) { 86 sessionStorage.setItem("bgNextState", JSON.stringify(state)); 87 }, 88 89 update(changes) { 90 this.setState({ 91 ...this.getState(), 92 ...changes, 93 }); 94 }, 95 96 clear() { 97 sessionStorage.removeItem("bgNextState"); 98 }, 99}; 100 101// 设置å¨ç»è¿æ¸¡ 102const setTransitions = () => { 103 DOM.bgNext.style.transition = `all ${ANIMATION.duration} ${ANIMATION.easing}`; 104 DOM.navSearchWrapper.style.transition = `all ${ANIMATION.duration} ${ANIMATION.easing}`; 105 106 if (DOM.searchbox) { 107 DOM.searchbox.style.transition = `transform ${ANIMATION.duration} ${ANIMATION.easing}`; 108 } 109 110 if (DOM.divider) { 111 DOM.divider.style.transition = !DOM.searchbox 112 ? `all ${ANIMATION.duration} ${ANIMATION.easing}` 113 : `transform ${ANIMATION.duration} ${ANIMATION.easing}`; 114 } 115}; 116 117// åå§åå ç´ ç¶æ - ä¼ååççæ¬ 118const initElementStates = (isEntering, bgNextWidth, initialWidth, isFirstLoad = false) => { 119 // ç¡®ä¿å ç´ å¯è§æ§åä½ç½®éç½® 120 const resetElement = (element, styles) => { 121 if (element) { 122 element.style.cssText = styles; 123 // 强å¶éç» 124 void element.offsetWidth; 125 } 126 }; 127 128 // éç½®ææå ç´ çè¿æ¸¡ 129 [DOM.bgNext, DOM.navSearchWrapper, DOM.searchbox, DOM.divider].forEach(el => {
130 if (el) el.style.transition = 'none'; 131 }); 132 133 // åå§å导èªå®¹å¨å®½åº¦ - ç§»é¤overflow设置 134 resetElement(DOM.navSearchWrapper, ` 135 width: ${initialWidth}px; 136 `); 137 // åå§å bg-next å ç´ 138 resetElement(DOM.bgNext, ` 139 display: block; 140 opacity: ${isEntering ? "0" : "1"}; 141 transform: translateX(${isEntering ? "20px" : "0"}); 142 pointer-events: auto; 143 position: relative; 144 z-index: 1; 145 transition: none; 146 `); 147 148 if (!DOM.searchbox && DOM.divider) { 149 if (isEntering && !isFirstLoad) { 150 resetElement(DOM.divider, ` 151 display: block; 152 opacity: 0; 153 transform: translateX(${isEntering ? "20px" : "0"}); 154 transition: none; 155 `); 156 } 157 } 158 159 if (isEntering && !isFirstLoad) { 160 setInitialPositions(bgNextWidth); 161 } 162 163 // 强å¶éç»ææå ç´ 164 requestAnimationFrame(() => { 165 [DOM.bgNext, DOM.navSearchWrapper, DOM.searchbox, DOM.divider].forEach(el => { 166 if (el) void el.offsetWidth; 167 }); 168 }); 169}; 170 171// 设置åå§ä½ç½® 172const setInitialPositions = (bgNextWidth) => { 173 if (DOM.searchbox) { 174 DOM.searchbox.style.cssText = ` 175 transform: translateX(${bgNextWidth}px); 176 transition: none; 177 `; 178 } 179 if (DOM.divider) { 180 if (!DOM.searchbox) { 181 DOM.divider.style.cssText = ` 182 display: block; 183 opacity: 0; 184 transform: translateX(${bgNextWidth}px); 185 transition: none; 186 `; 187 } else { 188 DOM.divider.style.cssText = ` 189 transform: translateX(${bgNextWidth}px); 190 transition: none; 191 `; 192 } 193 } 194}; 195 196// ä¼åçå¨ç»æ§è¡å½æ° 197const animateElements = (isEntering, bgNextWidth, initialWidth) => { 198 // ä½¿ç¨ transform ä»£æ¿ width å¨ç»ä»¥æé«æ§è½ 199 const animate = () => { 200 setTransitions(); 201 202 // ä¼åå¨ç»æ§è½ 203 DOM.navSearchWrapper.style.willChange = 'transform, width'; 204 DOM.bgNext.style.willChange = 'transform, opacity'; 205 DOM.bgNext.style.pointerEvents = 'auto'; 206 DOM.bgNext.style.zIndex = '1'; 207 208 if (DOM.searchbox) DOM.searchbox.style.willChange = 'transform'; 209 if (DOM.divider) DOM.divider.style.willChange = 'transform, opacity'; 210 211 // ç¡®ä¿å¨å¨ç»å¼å§åoverflow为hidden 212 if (!window._searchWrapperState || !window._searchWrapperState.state) { 213 DOM.navSearchWrapper.style.overflow = "hidden"; 214 } 215 216 const elements = [ 217 [DOM.bgNext, { 218 opacity: isEntering ? "1" : "0", 219 transform: `translateX(${isEntering ? "0" : "20px"})`, 220 width: `${DOM.bgNext.offsetWidth}px`, 221 height: `${DOM.bgNext.offsetWidth}px`, 222 }], 223 [DOM.navSearchWrapper, { 224 width: `${initialWidth + (isEntering ? bgNextWidth : -bgNextWidth)}px` 225 }] 226 ]; 227 228 if (!isEntering) { 229 if (DOM.searchbox) { 230 elements.push([DOM.searchbox, { 231 transform: `translateX(${bgNextWidth}px)` // ç´æ¥ä½¿ç¨bgNextWidth 232 }]); 233 } 234 if (DOM.divider) { 235 elements.push([DOM.divider, { 236 opacity: DOM.searchbox ? "1" : "0", 237 transform: `translateX(${bgNextWidth}px)` // ç´æ¥ä½¿ç¨bgNextWidth 238 }]); 239 } 240 } else { 241 if (DOM.searchbox) { 242 elements.push([DOM.searchbox, { 243 transform: "translateX(0)" 244 }]); 245 } 246 if (DOM.divider) { 247 elements.push([DOM.divider, { 248 opacity: "1", 249 transform: "translateX(0)" 250 }]); 251 } 252 } 253 254 // ç§»é¤ä¹åçtransitionendäºä»¶ï¼æ¹ä¸ºä» å¨å¨ç»å®æåå¤ç 255 setTimeout(() => { 256 DOM.navSearchWrapper.style.willChange = ''; 257 DOM.bgNext.style.willChange = ''; 258 DOM.bgNext.style.pointerEvents = 'auto'; // ç¡®ä¿å¨ç»ç»æåä»å¯ç¹å» 259 if (DOM.searchbox) DOM.searchbox.style.willChange = ''; 260 if (DOM.divider) DOM.divider.style.willChange = ''; 261 262 // ä» å¨éæç« æ é¢åæ¢ç¶ææ¶éç½®overflow
263 if (!window._searchWrapperState || !window._searchWrapperState.state) { 264 requestAnimationFrame(() => { 265 DOM.navSearchWrapper.style.overflow = "unset"; 266 }); 267 } 268 }, ANIMATION.durationMs); 269 270 elements.forEach(([element, styles]) => { 271 if (element) { 272 Object.assign(element.style, styles); 273 } 274 }); 275 }; 276 277 // ä½¿ç¨ RAF ç¡®ä¿å¨ç»æµç 278 requestAnimationFrame(animate); 279}; 280 281// 页é¢è¿æ¸¡å¤ç 282const handlePageTransition = (isHomePage, state) => { 283 // æ·»å æ¸ çé»è¾ 284 const cleanupAnimations = () => { 285 if (window._searchWrapperState) { 286 window._searchWrapperState.state = false; 287 if (window._searchWrapperState.hideTimeout) { 288 clearTimeout(window._searchWrapperState.hideTimeout); 289 } 290 if (window._searchWrapperState.scrollRAF) { 291 cancelAnimationFrame(window._searchWrapperState.scrollRAF); 292 } 293 } 294 295 // éç½®å¯¼èªæ ·å¼ 296 DOM.navSearchWrapper.style.overflow = "unset"; 297 DOM.navSearchWrapper.style.width = "auto"; 298 delete DOM.navSearchWrapper.dataset.scrollswap; 299 DOM.navSearchWrapper.style.setProperty("--dw", "0"); 300 301 if (isHomePage) { 302 // ç¡®ä¿å¨ä¸»é¡µæ¶ bg-next å¯ç¹å» 303 DOM.bgNext.style.pointerEvents = 'auto'; 304 DOM.bgNext.style.zIndex = '1'; 305 } 306 }; 307 308 if (isHomePage === state.lastPageWasHome) { 309 cleanupAnimations(); 310 DOM.bgNext.style.display = isHomePage ? "block" : "none"; 311 DOM.bgNext.style.transform = isHomePage ? "none" : "translateX(20px)"; 312 DOM.bgNext.style.opacity = isHomePage ? "1" : "0"; 313 return; 314 } 315 316 // ä½¿ç¨ Performance API ä¼åå¨ç»æ¶æº 317 if (window.performance && window.performance.now) { 318 const startTime = performance.now(); 319 320 // æ·»å 鲿ï¼é¿å å¿«é忢坼è´çå¨ç»é®é¢ 321 if (state.transitionTimer) { 322 cancelAnimationFrame(state.transitionTimer); 323 } 324 325 state.transitionTimer = requestAnimationFrame(async () => { 326 // ç¡®ä¿å¨é主页åå§åå馿¬¡è¿å ¥ä¸»é¡µæ¶éæ°åå§å 327 if (isHomePage && state.initializedOutsideHome && !InitController.initialized) { 328 await InitController.init(); 329 } 330 331 if (!InitController.initialized) { 332 await InitController.init(); 333 } 334 335 const getMeasuredWidth = (element) => { 336 return new Promise(resolve => { 337 const clone = element.cloneNode(true); 338 clone.style.cssText = ` 339 all: initial !important; 340 position: fixed !important; 341 visibility: hidden !important; 342 display: block !important; 343 max-width: none !important; 344 width: auto !important; 345 height: auto !important; 346 margin: 0 !important; 347 padding: ${getComputedStyle(element).padding} !important; 348 font: ${getComputedStyle(element).font} !important; 349 `; 350 351 requestAnimationFrame(() => { 352 document.body.appendChild(clone); 353 requestAnimationFrame(() => { 354 const width = clone.getBoundingClientRect().width; 355 document.body.removeChild(clone); 356 resolve(Math.ceil(width)); 357 }); 358 }); 359 }); 360 }; 361 362 try { 363 const isWebKit = BrowserDetect.isWebKit(); 364 const originalDisplay = DOM.bgNext.style.display; 365 366 // 临æ¶éèææå¯è½å½±å宽度çå ç´ 367 DOM.bgNext.style.display = 'none'; 368 if (DOM.searchbox) DOM.searchbox.style.visibility = 'hidden'; 369 if (DOM.divider) DOM.divider.style.visibility = 'hidden'; 370
371 let wrapperWidth = Math.ceil(DOM.navSearchWrapper.getBoundingClientRect().width); 372 373 // æ¢å¤å ç´ æ¾ç¤º 374 DOM.bgNext.style.display = originalDisplay; 375 if (DOM.searchbox) DOM.searchbox.style.visibility = ''; 376 if (DOM.divider) DOM.divider.style.visibility = ''; 377 378 const bgWidth = await WidthCalculator.measure(DOM.bgNext, { 379 useCache: true, 380 additionalStyles: 'margin: 0 !important; padding: inherit !important;' 381 }); 382 383 const gap = parseFloat(getComputedStyle(DOM.navSearchWrapper).gap) || 0; 384 const finalBgWidth = Math.ceil(bgWidth + gap); 385 386 // åªå¨é主页çWebKitç¯å¢ä¸è¡¥å 宽度 387 if (isWebKit && !isHomePage) { 388 wrapperWidth = Math.ceil(wrapperWidth + finalBgWidth); 389 } 390 391 animateTransition(isHomePage, state, finalBgWidth, wrapperWidth); 392 } catch (error) { 393 console.error('è¿æ¸¡å¤±è´¥:', error); 394 cleanupAnimations(); 395 } 396 }); 397 } 398}; 399 400// æ§è¡è¿æ¸¡å¨ç» 401const animateTransition = (isEntering, state, bgNextWidth, initialWidth) => { 402 403 // å¢å å®¹éæ£æµ 404 const currentWidth = DOM.navSearchWrapper.offsetWidth; 405 if(Math.abs(initialWidth - currentWidth) > 50){ 406 console.warn('Width deviation detected, recalculating...'); 407 initialWidth = currentWidth; 408 } 409 410 if (state.isTransitioning) return; 411 412 StateManager.update({ 413 isTransitioning: true, 414 }); 415 416 // 使ç¨åå¨çæµé宽度è¿è¡éªè¯åä¿®æ£ 417 if (state.measuredWidths) { 418 const currentInitialWidth = Math.ceil(DOM.navSearchWrapper.getBoundingClientRect().width); 419 // ä¿®å¤ï¼å¦ææ¯ç¬¬ä¸æ¬¡æ§è¡éåºå¨ç»ä¸å½åæ¯ä¸»é¡µï¼åå§å®½åº¦éè¦åå»ä¸ä¸ª bgNextWidth 420 if (!state.firstExitDone && !isEntering && location.pathname === "/") { 421 initialWidth -= bgNextWidth; 422 state.firstExitDone = true; 423 StateManager.setState(state); 424 } 425 // æ£æ¥å®½åº¦å·®å¼ 426 if (Math.abs(currentInitialWidth - state.measuredWidths.initial) > 5) { 427 console.debug('Width mismatch detected, recalculating...'); 428 initialWidth = currentInitialWidth; 429 } 430 } 431 432 initElementStates(isEntering, bgNextWidth, initialWidth); 433 434 [DOM.bgNext, DOM.navSearchWrapper, DOM.searchbox, DOM.divider].forEach((el) => { 435 if (el) void el.offsetWidth; 436 }); 437 438 requestAnimationFrame(() => { 439 setTransitions(); 440 animateElements(isEntering, bgNextWidth, initialWidth); 441 442 // ä¿®æ¹å¨ç»å®æåçå¤ç 443 setTimeout(() => { 444 if (!isEntering) { 445 DOM.bgNext.style.display = "none"; 446 DOM.navSearchWrapper.style.width = "auto"; 447 // ç¡®ä¿å¨non-home页颿¶æ£ç¡®è®¾ç½®overflow 448 if (!window._searchWrapperState || !window._searchWrapperState.state) { 449 DOM.navSearchWrapper.style.overflow = "unset"; 450 } 451 if (!DOM.searchbox && DOM.divider) { 452 DOM.divider.style.display = "none"; 453 } 454 [DOM.searchbox, DOM.divider].forEach((el) => { 455 if (el) { 456 el.style.transition = "none"; 457 el.style.transform = ""; 458 } 459 }); 460 } 461 StateManager.update({ 462 isTransitioning: false, 463 }); 464 }, ANIMATION.durationMs); 465 }); 466}; 467 468// æ¾ç¤ºæéèbgNextå ç´ - ä¼ååççæ¬ 469const showBgNext = async () => { 470 const isHomePage = 471 location.pathname === "/" || location.pathname === "/index.php"; 472 const state = StateManager.getState(); 473 474 if (!state.initialized) { 475 const widths = await InitController.init(); 476 state.initialized = true; 477 state.measuredWidths = widths; 478 StateManager.setState(state); 479 } 480 481 if (state.isTransitioning) {
482 // å³ä½¿å¨è¿æ¸¡ç¶æï¼ä¹è¦ç¡®ä¿å¨ä¸»é¡µæ¶ bg-next å¯ç¹å» 483 if (isHomePage) { 484 DOM.bgNext.style.pointerEvents = 'auto'; 485 DOM.bgNext.style.zIndex = '1'; 486 } 487 return; 488 } 489 490 // å¤ç馿¬¡å è½½éä¸»é¡µçæ åµ 491 if (!state.initialized && !isHomePage) { 492 state.initializedOutsideHome = true; 493 state.initialized = true; 494 StateManager.setState(state); 495 DOM.bgNext.style.display = 'none'; 496 return; 497 } 498 499 // å¤çä»é䏻页馿¬¡åå°ä¸»é¡µçæ åµ 500 if (isHomePage && state.initializedOutsideHome && state.firstHomeTransition) { 501 try { 502 const widths = await InitController.init(); 503 if (!widths) return; 504 505 state.firstHomeTransition = false; 506 state.measuredWidths = widths; 507 StateManager.setState(state); 508 509 // 设置åå§ç¶æ 510 initElementStates(true, widths.bgNextWidth, widths.wrapperWidth, false); 511 512 // ä½¿ç¨ RAF é¾ç¡®ä¿å¨ç»æ£ç¡®æ§è¡ 513 requestAnimationFrame(() => { 514 DOM.bgNext.style.opacity = '0'; 515 DOM.bgNext.style.transform = 'translateX(20px)'; 516 DOM.bgNext.style.display = 'block'; 517 requestAnimationFrame(() => { 518 setTransitions(); 519 animateElements(true, widths.bgNextWidth, widths.wrapperWidth); 520 }); 521 }); 522 return; 523 } catch (error) { 524 console.error('主页åå§å失败:', error); 525 state.firstHomeTransition = false; 526 StateManager.setState(state); 527 return; 528 } 529 } 530 531 // å¤ç常è§çé¦é¡µé¦æ¬¡å è½½ 532 if (state.firstLoad && !state.initialized && isHomePage) { 533 try { 534 const widths = await InitController.init(); 535 if (!widths) return; 536 537 // ç¡®ä¿DOMå·²åå¤å°±ç»ª 538 await new Promise(resolve => { 539 if (document.readyState === 'complete') { 540 resolve(); 541 } else { 542 window.addEventListener('load', resolve, { once: true }); 543 } 544 }); 545 546 state.initialized = true; 547 state.measuredWidths = widths; 548 StateManager.setState(state); 549 550 // 使ç¨RAF龿§è¡åå§å¨ç» 551 requestAnimationFrame(() => { 552 initElementStates(true, widths.bgNextWidth, widths.wrapperWidth, true); 553 state.firstLoad = false; 554 StateManager.setState(state); 555 556 requestAnimationFrame(() => { 557 animateElements(true, widths.bgNextWidth, widths.wrapperWidth); 558 }); 559 }); 560 } catch (error) { 561 console.error('åå§å失败:', error); 562 state.firstLoad = false; 563 StateManager.setState(state); 564 } 565 return; 566 } 567 568 handlePageTransition(isHomePage, state); 569}; 570 571// åå§åæç« æ é¢è¡ä¸º 572const initArticleTitleBehavior = () => { 573 DOM.navSearchWrapper.style.overflow = "unset"; 574 575 if (window._searchWrapperState) { 576 const navTitle = DOM.navSearchWrapper.querySelector(".nav-article-title"); 577 if (navTitle) { 578 navTitle.remove(); 579 } 580 delete DOM.navSearchWrapper.dataset.scrollswap; 581 DOM.navSearchWrapper.style.setProperty("--dw", "0"); 582 window._searchWrapperState = null; 583 } 584 585 if (!_iro.land_at_home) { 586 const searchWrapperState = { 587 state: false, 588 navElement: null, 589 navTitle: null, 590 entryTitle: null, 591 titlePadding: 20, 592 scrollTimeout: null, 593 hideTimeout: null, 594 headerElement: null, 595 596 init() { 597 this.navTitle = DOM.navSearchWrapper.querySelector(".nav-article-title"); 598 this.entryTitle = document.querySelector(".entry-title"); 599 this.navElement = DOM.navSearchWrapper.querySelector("nav"); 600 this.header = document.querySelector("header"); 601 602 if (!this.navTitle) { 603 this.navTitle = document.createElement("div"); 604 this.navTitle.classList.add("nav-article-title"); 605 this.navTitle.style.opacity = "0";
606 DOM.navSearchWrapper.firstElementChild.insertAdjacentElement( 607 "afterend", 608 this.navTitle 609 ); 610 611 this.header.addEventListener("mouseenter", () => { 612 if (this.hideTimeout) { 613 clearTimeout(this.hideTimeout); 614 this.hideTimeout = null; 615 } 616 if (this.entryTitle && this.entryTitle.getBoundingClientRect().top < 0) { 617 this.hide(); 618 } 619 }); 620 621 this.header.addEventListener("mouseleave", () => { 622 if (this.hideTimeout) { 623 clearTimeout(this.hideTimeout); 624 } 625 if (this.entryTitle && this.entryTitle.getBoundingClientRect().top < 0) { 626 this.hideTimeout = setTimeout(() => { 627 this.show(); 628 this.hideTimeout = null; 629 }, 3000); 630 } 631 }); 632 633 this.navElement.addEventListener("transitionend", (event) => { 634 if (event.target !== this.navElement && event.target !== this.header) return; 635 this.navTitle.style.opacity = window.getComputedStyle(this.navElement).transform == "none" ? "0" : "1"; 636 if (document.querySelector(".entry-title")) { 637 DOM.navSearchWrapper.style.overflow = window.getComputedStyle(this.navElement).transform === "none" ? "unset" : "hidden"; 638 } 639 }); 640 641 this.navElement.addEventListener("transitionstart", (event) => { 642 if (event.target !== this.navElement && event.target !== this.header) return; 643 if (document.querySelector(".entry-title")) { 644 DOM.navSearchWrapper.style.overflow = "hidden"; 645 } 646 this.navTitle.style.opacity = "1"; 647 }); 648 } 649 this.updateTitle(); 650 }, 651 652 updateTitle() { 653 if (this.entryTitle) { 654 this.navTitle.textContent = this.entryTitle.textContent; 655 this.navTitle.style.display = "block"; 656 } else { 657 this.navTitle.style.display = "none"; 658 } 659 }, 660 661 show() { 662 if (this.state || !this.entryTitle) return; 663 const navSearchWrapper = DOM.navSearchWrapper; 664 navSearchWrapper.dataset.scrollswap = "true"; 665 666 requestAnimationFrame(() => { 667 // å建临æ¶å¯¼èªå®¹å¨ 668 const tempNav = document.createElement('div'); 669 tempNav.style.cssText = ` 670 position: absolute; 671 visibility: hidden; 672 white-space: nowrap; 673 display: flex; 674 align-items: center; 675 padding: ${window.getComputedStyle(this.navElement).padding}; 676 margin: ${window.getComputedStyle(this.navElement).margin}; 677 gap: ${window.getComputedStyle(this.navElement).gap}; 678 `; 679 document.body.appendChild(tempNav); 680 681 // å é导èªé¡¹å¹¶ä¿æå®æ´æ ·å¼ 682 const menuItems = Array.from(this.navElement.children); 683 menuItems.forEach(item => { 684 const clone = item.cloneNode(true); 685 const computedStyle = window.getComputedStyle(item); 686 clone.style.cssText = Array.from(computedStyle).reduce((str, prop) => { 687 return `${str}${prop}:${computedStyle.getPropertyValue(prop)};`; 688 }, ''); 689 tempNav.appendChild(clone); 690 }); 691 692 const actualNavWidth = Math.ceil(tempNav.getBoundingClientRect().width); 693 694 // åå»ºä¸´æ¶æ é¢å®¹å¨ 695 const tempTitle = document.createElement('div'); 696 const titleStyle = window.getComputedStyle(this.navTitle); 697 tempTitle.style.cssText = `
698 position: absolute; 699 visibility: hidden; 700 white-space: nowrap; 701 font-size: ${titleStyle.fontSize}; 702 font-family: ${titleStyle.fontFamily}; 703 font-weight: ${titleStyle.fontWeight}; 704 letter-spacing: ${titleStyle.letterSpacing}; 705 padding: ${titleStyle.padding}; 706 margin: ${titleStyle.margin}; 707 `; 708 tempTitle.textContent = this.navTitle.textContent; 709 document.body.appendChild(tempTitle); 710 711 const actualTitleWidth = Math.ceil(tempTitle.getBoundingClientRect().width); 712 713 // ç´æ¥ä½¿ç¨å®½åº¦å·®å¼ï¼ä¸åæ·»å è¡¥å¿ç©ºé´ 714 const deltaWidth = actualTitleWidth - actualNavWidth; 715 716 navSearchWrapper.style.setProperty("--dw", `${deltaWidth}px`); 717 718 // æ¸ ç临æ¶å ç´ 719 document.body.removeChild(tempNav); 720 document.body.removeChild(tempTitle); 721 }); 722 this.state = true; 723 }, 724 725 hide() { 726 if (!this.state) return; 727 const navSearchWrapper = DOM.navSearchWrapper; 728 delete navSearchWrapper.dataset.scrollswap; 729 navSearchWrapper.style.setProperty("--dw", "0"); 730 if (document.querySelector(".entry-title")) { 731 navSearchWrapper.style.overflow = "unset"; 732 } 733 this.state = false; 734 }, 735 736 handleScroll() { 737 // ä½¿ç¨ RAF ä¼åæ»å¨æ§è½ 738 if (!this.scrollRAF) { 739 this.scrollRAF = requestAnimationFrame(() => { 740 if (this.entryTitle) { 741 const rect = this.entryTitle.getBoundingClientRect(); 742 if (rect.top < 0) { 743 this.show(); 744 } else { 745 this.hide(); 746 } 747 } 748 this.scrollRAF = null; 749 }); 750 } 751 }, 752 }; 753 754 searchWrapperState.init(); 755 756 const scrollHandler = () => searchWrapperState.handleScroll(); 757 window.addEventListener("scroll", scrollHandler, { passive: true }); 758 window.addEventListener("resize", () => searchWrapperState.show(), { 759 passive: true, 760 }); 761 762 scrollHandler(); 763 764 window._searchWrapperState = searchWrapperState; 765 } else { 766 requestAnimationFrame(() => { 767 DOM.navSearchWrapper.style.overflow = "unset"; 768 }); 769 } 770 771 // å¢å å»¶è¿æ£æµ 772 setTimeout(() => { 773 if(window._searchWrapperState){ 774 window._searchWrapperState.handleScroll(); 775 // 强å¶éç®å®½åº¦ 776 window._searchWrapperState.show(); 777 } 778 }, 300); // çå¾ æµè§å¨æ»å¨æ¢å¤ 779}; 780 781// åå§åææå¨ç» 782const initAnimations = () => { 783 StateManager.init(); 784 showBgNext(); 785 initArticleTitleBehavior(); 786}; 787 788// ä¼åçäºä»¶çå¬å¨ 789const addEventListeners = () => { 790 const events = [ 791 ["pjax:send", () => { 792 WidthCalculator.clearCache(); 793 // æ¸ çä¹åçå¨ç»ç¶æ 794 if (window._searchWrapperState) { 795 if (window._searchWrapperState.hideTimeout) { 796 clearTimeout(window._searchWrapperState.hideTimeout); 797 } 798 if (window._searchWrapperState.scrollRAF) { 799 cancelAnimationFrame(window._searchWrapperState.scrollRAF); 800 } 801 window._searchWrapperState.state = false; 802 } 803 804 StateManager.update({ 805 lastPageWasHome: location.pathname === "/" || location.pathname === "/index.php", 806 isTransitioning: false // 强å¶éç½®è¿æ¸¡ç¶æ 807 }); 808 }], 809 ["pjax:complete", () => { 810 requestAnimationFrame(() => { 811 // ç¡®ä¿ææç¶æéç½®
812 DOM.navSearchWrapper.style.overflow = "unset"; 813 DOM.navSearchWrapper.style.width = "auto"; 814 delete DOM.navSearchWrapper.dataset.scrollswap; 815 DOM.navSearchWrapper.style.setProperty("--dw", "0"); 816 817 showBgNext(); 818 if (window._searchWrapperState) { 819 window._searchWrapperState.init(); 820 window._searchWrapperState.handleScroll(); 821 } else { 822 initArticleTitleBehavior(); 823 } 824 }); 825 }], 826 ["DOMContentLoaded", initAnimations], 827 ['popstate', () => { 828 const isHomePage = location.pathname === "/" || location.pathname === "/index.php"; 829 if (isHomePage) { 830 StateManager.clear(); 831 StateManager.init(); 832 showBgNext(); 833 } 834 }] 835 ]; 836 837 events.forEach(([event, handler]) => { 838 document.addEventListener(event, handler); 839 }); 840}; 841 842// åå§åæ¶è°ç¨äºä»¶çå¬å¨è®¾ç½® 843addEventListeners(); 844 845// æ°å¢å®½åº¦æµéå·¥å · 846const WidthCalculator = { 847 cache: new Map(), 848 849 async measure(element, options = {}) { 850 if (!element) return 0; 851 852 const cacheKey = element.id || element.className; 853 if (options.useCache && this.cache.has(cacheKey)) { 854 return this.cache.get(cacheKey); 855 } 856 857 const clone = element.cloneNode(true); 858 clone.style.cssText = ` 859 position: fixed !important; 860 visibility: hidden !important; 861 display: block !important; 862 transform: none !important; 863 transition: none !important; 864 animation: none !important; 865 opacity: 0 !important; 866 pointer-events: none !important; 867 z-index: -9999 !important; 868 ${options.additionalStyles || ''} 869 `; 870 871 document.body.appendChild(clone); 872 873 // çå¾ å å¸§ä»¥ç¡®ä¿æ ·å¼åºç¨å®æ 874 await new Promise(resolve => { 875 let frames = 3; 876 function waitFrames() { 877 if (--frames <= 0) { 878 resolve(); 879 } else { 880 requestAnimationFrame(waitFrames); 881 } 882 } 883 requestAnimationFrame(waitFrames); 884 }); 885 886 const rect = clone.getBoundingClientRect(); 887 const width = Math.ceil(rect.width); 888 889 document.body.removeChild(clone); 890 891 if (options.useCache) { 892 this.cache.set(cacheKey, width); 893 } 894 895 return width; 896 }, 897 898 clearCache() { 899 this.cache.clear(); 900 } 901}; 902 903// æ°å¢åå§åæ§å¶å¨ 904const InitController = { 905 initialized: false, 906 initializing: false, 907 queue: [], 908 909 async init() { 910 if (this.initialized || this.initializing) return; 911 this.initializing = true; 912 913 // ç¡®ä¿åä½å è½½å®æ 914 await document.fonts.ready; 915 // å¢å å»¶è¿ç¡®ä¿å¸å±ç¨³å® 916 await new Promise(resolve => setTimeout(resolve, 200)); 917 918 // 强å¶éæ°å¸å±å¹¶æµé 919 const measure = async () => { 920 // ä¿ååå§ç¶æ 921 const originalStyles = { 922 wrapper: DOM.navSearchWrapper.style.cssText, 923 bgNext: DOM.bgNext.style.cssText, 924 searchbox: DOM.searchbox ? DOM.searchbox.style.cssText : '', 925 divider: DOM.divider ? DOM.divider.style.cssText : '' 926 }; 927 928 // éç½®æææ ·å¼ä»¥è·ååç¡®æµé 929 DOM.navSearchWrapper.style.cssText = ` 930 overflow: hidden !important; 931 width: auto !important; 932 transition: none !important; 933 transform: none !important; 934 `; 935 936 DOM.bgNext.style.cssText = ` 937 display: none !important; 938 transition: none !important; 939 transform: none !important; 940 `; 941 942 if (DOM.searchbox) DOM.searchbox.style.visibility = 'hidden'; 943 if (DOM.divider) DOM.divider.style.visibility = 'hidden'; 944 945 // 强å¶éæ
946 void DOM.navSearchWrapper.offsetWidth; 947 948 // è·ååºç¡å®½åº¦ 949 let wrapperWidth = Math.ceil(DOM.navSearchWrapper.getBoundingClientRect().width); 950 951 // æµé bg-next 952 DOM.bgNext.style.cssText = ` 953 position: relative !important; 954 visibility: visible !important; 955 display: block !important; 956 opacity: 0 !important; 957 transform: none !important; 958 transition: none !important; 959 `; 960 961 void DOM.bgNext.offsetWidth; 962 963 const bgWidth = Math.ceil(DOM.bgNext.getBoundingClientRect().width); 964 const gap = parseFloat(getComputedStyle(DOM.navSearchWrapper).gap) || 0; 965 const finalBgWidth = Math.ceil(bgWidth + gap); 966 967 // æ¢å¤åå§æ ·å¼ 968 DOM.navSearchWrapper.style.cssText = originalStyles.wrapper; 969 DOM.bgNext.style.cssText = originalStyles.bgNext; 970 if (DOM.searchbox) DOM.searchbox.style.cssText = originalStyles.searchbox; 971 if (DOM.divider) DOM.divider.style.cssText = originalStyles.divider; 972 973 return { 974 bgNextWidth: finalBgWidth,
975 wrapperWidth: wrapperWidth 976 }; 977 }; 978 979 const measurements = await measure(); 980 981 // äºæ¬¡ç¡®è®¤æµé 982 await new Promise(resolve => requestAnimationFrame(resolve)); 983 const secondMeasure = await measure(); 984 985 // å¦æä¸¤æ¬¡æµéå·®å¼è¿å¤§ï¼ä½¿ç¨ç¬¬äºæ¬¡çç»æ 986 const finalMeasurements = { 987 bgNextWidth: Math.abs(measurements.bgNextWidth - secondMeasure.bgNextWidth) > 2 988 ? secondMeasure.bgNextWidth 989 : measurements.bgNextWidth, 990 wrapperWidth: Math.abs(measurements.wrapperWidth - secondMeasure.wrapperWidth) > 2 991 ? secondMeasure.wrapperWidth 992 : measurements.wrapperWidth 993 }; 994 995 this.initialized = true; 996 this.initializing = false; 997 998 return finalMeasurements; 999 } 1000}; 1001 1002// æ·»å æµè§å¨æ£æµå·¥å · 1003const BrowserDetect = { 1004 isWebKit: () => { 1005 return 'WebkitAppearance' in document.documentElement.style; 1006 } 1007} 1008};//iro_nav function 1009 1010//以ä¸ä» æ°çå¯¼èªæ ï¼ä»¥ä¸æ¯éç¨é¨å 1011document.addEventListener("DOMContentLoaded", () => { 1012 1013 //鲿¢åèåéåå å 1014 const menuItems = document.querySelectorAll('nav .menu > li'); 1015 let activeSubMenu = null; 1016 1017 menuItems.forEach(item => { 1018 const subMenu = item.querySelector('.sub-menu'); 1019 1020 if (!subMenu) return; 1021 1022 //é¼ æ ç§»å ¥æ¶æ¿æ´»åèå 1023 item.addEventListener('mouseenter', () => { 1024 if (activeSubMenu && activeSubMenu !== subMenu) { 1025 //æä¸ä» æä¸ä¸ªæ¿æ´» 1026 activeSubMenu.classList.remove('active'); 1027 } 1028 1029 //æ´æ°å¹¶æ¿æ´»å½ååèå 1030 subMenu.classList.add('active'); 1031 activeSubMenu = subMenu; 1032 }); 1033 }); 1034 //æ¾å å ç»æ 1035 1036 //åèåå¯¹é½ 1037 const subMenus = document.querySelectorAll("nav .menu > li .sub-menu"); 1038 1039 subMenus.forEach(subMenu => { 1040 const MainMenu = subMenu.parentElement; 1041 1042 // è·å渲æåç宽度 1043 const MainMenuWidth = MainMenu.getBoundingClientRect().width; 1044 const subMenuWidth = subMenu.getBoundingClientRect().width; 1045 1046 // å移计ç®ï¼ç¡®ä¿åèåå± ä¸ 1047 const offsetX = (subMenuWidth - MainMenuWidth) / 2; 1048 1049 // 设置åå§æ ·å¼ 1050 const BasicSubMenuStyle = `translateY(-10px) translateX(${offsetX}px)`; 1051 subMenu.style.transform = BasicSubMenuStyle; 1052 1053 // 设置åç§»é 1054 MainMenu.addEventListener("mouseenter", () => { 1055 subMenu.style.transform = `translateY(0) translateX(${offsetX}px)`; 1056 }); 1057 MainMenu.addEventListener("mouseleave", () => { 1058 subMenu.style.transform = BasicSubMenuStyle; 1059 }); 1060 }); 1061 //åèå对é½ç»æ 1062 1063 //以䏿¯çªå±/ç§»å¨ç«¯éç¨é¨å 1064 //ç§»å¨ç«¯èåå¼å ³ 1065 //éç¨é¨å 1066 let moNavButton = document.querySelector(".mo-nav-button"); 1067 let moTocButton = document.querySelector(".mo-toc-button"); 1068 let moNavMenu = document.querySelector(".mobile-nav"); 1069 let moTocMenu = document.querySelector(".mo_toc_panel"); 1070 let moHeader = document.querySelector(".site-header"); 1071 let navTransitionHandler = null; 1072 let panelTransitionHandler = null; 1073 1074 let panelOrderAnime = null; 1075 1076 moUserMenu = document.querySelector(".mo-user-menu"); 1077 if (!moUserMenu) { 1078 TocButtonStat (); 1079 1080 function TocButtonStat () { 1081 document.addEventListener("tocEvent",function(event){ // page/index.js ç®å½çæäºä»¶ 1082 1083 let haveToc = document.querySelector("#main-container .toc-container .toc"); 1084 let haveContent = event.detail; 1085 1086 if (haveToc && haveContent) { // 䏿¹ç¨æ·æ åç®å½äºéä¸ï¼æ¤å¤æ¯æ²¡æç¨æ·æ è¿æ²¡æç®å½çæ åµ 1087 moTocButton.style.transform = 'translateY(0)'; 1088 } else { 1089 moTocButton.style.transform = 'translateY(-100%)'; 1090 } 1091 1092 }) 1093 } 1094 1095 document.addEventListener('pjax:complete', function() { 1096 TocButtonStat (); 1097 }); 1098 } 1099 1100 //å¨ç»çå¬ 1101 function isAnyPanelOpen() { 1102 return moNavMenu.classList.contains("open") || moTocMenu.classList.contains("open"); 1103 } 1104 1105 function isHeaderHover() { 1106 const bgColor = getComputedStyle(moHeader).backgroundColor; 1107 return bgColor !== "transparent" && bgColor !== "rgba(0, 0, 0, 0)"; //ä¸éæå³è§ä¸ºHover 1108 } 1109 1110 function openMenu(panel, button) { 1111 1112 if (isHeaderHover()) { //hoverä¼äº§çèæ¯å¨ç»ï¼å¹²æ°ç¸å ³åè½ï¼ä½æ¯æ é夿å¨ç»å åï¼ç´æ¥å¼åºå³å¯ 1113 panel.classList.add("open"); 1114 button.classList.add("open"); 1115 moHeader.classList.add("bg"); 1116 return; 1117 } 1118 1119 if (navTransitionHandler) { 1120 moHeader.removeEventListener("transitionend", navTransitionHandler); 1121 navTransitionHandler = null; 1122 panel.classList.add("open"); 1123 button.classList.add("open"); 1124 moHeader.classList.add("bg"); 1125 return; 1126 } 1127 1128 // å ç»å¯¼èªæ æ·»å èæ¯ 1129 if (!moHeader.classList.contains("bg")) { 1130 moHeader.classList.add("bg"); 1131 button.classList.add("open"); 1132 navTransitionHandler = function(e) { 1133 if (e.propertyName === "background-color") { 1134 panel.classList.add("open"); 1135 moHeader.removeEventListener("transitionend", navTransitionHandler); 1136 navTransitionHandler = null; 1137 } 1138 }; 1139 moHeader.addEventListener("transitionend", navTransitionHandler); 1140 } else {
1141 // å·²æèæ¯ 1142 panel.classList.add("open"); 1143 button.classList.add("open"); 1144 } 1145 } 1146 1147 function closeMenu(panel, button,CloseDirect = false) { 1148 1149 if (CloseDirect){ //ç´æ¥å ³éï¼hoverä¸éè¦èèèæ¯å¨ç»é¡ºåº 1150 panel.classList.remove("open"); 1151 button.classList.remove("open"); 1152 moHeader.classList.remove("bg"); 1153 return; 1154 } 1155 1156 if (panelTransitionHandler) { 1157 panel.removeEventListener("transitionend", panelTransitionHandler); 1158 panelTransitionHandler = null; 1159 if (!isAnyPanelOpen()) { 1160 moHeader.classList.remove("bg"); 1161 } 1162 return; 1163 } 1164 1165 panel.classList.remove("open"); 1166 button.classList.remove("open"); 1167 1168 panelTransitionHandler = function(e) { 1169 if (e.propertyName === "max-height") { 1170 // ææé¢æ¿é½å ³éåææ¤éå¯¼èªæ èæ¯ 1171 if (!isAnyPanelOpen()) { 1172 moHeader.classList.remove("bg"); 1173 } 1174 panel.removeEventListener("transitionend", panelTransitionHandler); 1175 panelTransitionHandler = null; 1176 } 1177 }; 1178 panel.addEventListener("transitionend", panelTransitionHandler); 1179 } 1180 1181 function closeThenOpen(oldPanel, newPanel) { 1182 let oldButton, newButton; 1183 // æ ¹æ®é¢æ¿å¤æå¯¹åºæé® 1184 if (oldPanel === moNavMenu) { 1185 oldButton = moNavButton; 1186 } else if (oldPanel === moTocMenu) { 1187 oldButton = moTocButton; 1188 } 1189 1190 if (newPanel === moNavMenu) { 1191 newButton = moNavButton; 1192 } else if (newPanel === moTocMenu) { 1193 newButton = moTocButton; 1194 } 1195 1196 closeMenu(oldPanel,oldButton); 1197 banAllButton(); //å¨ç»æé´ç¦æ¢äº¤äº 1198 panelOrderAnime = function(e) { 1199 if (e.propertyName === "max-height") { 1200 oldPanel.removeEventListener("transitionend", panelOrderAnime); 1201 openMenu(newPanel, newButton); 1202 activeAllButton(); 1203 } 1204 } 1205 oldPanel.addEventListener("transitionend", panelOrderAnime); 1206 } 1207 1208 function banAllButton () { 1209 moNavButton.style.pointerEvents = "none"; 1210 moTocButton.style.pointerEvents = "none"; 1211 } 1212 function activeAllButton() { 1213 moNavButton.style.pointerEvents = "auto"; 1214 moTocButton.style.pointerEvents = "auto"; 1215 } 1216 1217 // 颿¿ 1218 moNavButton.addEventListener("click", function (event) { 1219 event.stopPropagation(); 1220 1221 if (moTocMenu.classList.contains("open")) { 1222 closeThenOpen(moTocMenu,moNavMenu); 1223 return; 1224 } 1225 if (moNavMenu.classList.contains("open")) { 1226 closeMenu(moNavMenu, moNavButton,isHeaderHover()); 1227 } else { 1228 openMenu(moNavMenu, moNavButton); 1229 } 1230 }); 1231 1232 moTocButton.addEventListener("click", function (event) { 1233 event.stopPropagation(); 1234 1235 if (moNavMenu.classList.contains("open")) { 1236 closeThenOpen(moNavMenu,moTocMenu); 1237 generateMoToc(); 1238 return; 1239 } 1240 if (moTocMenu.classList.contains("open")) { 1241 closeMenu(moTocMenu, moTocButton,isHeaderHover()); 1242 } else { 1243 openMenu(moTocMenu, moTocButton); 1244 generateMoToc(); 1245 } 1246 }); 1247 1248 let moUserOption = document.querySelector(".mo_toc_panel .mo-user-options"); 1249 function generateMoToc() { 1250 //å¤å¶èå 1251 let mainToc = document.querySelector("#main-container .toc-container .toc"); 1252 let headToc = document.querySelector(".site-header .mo_toc_panel .mo_toc"); 1253 1254 if (mainToc && headToc) { //é½åå¨ 1255 if (mainToc.hasChildNodes()) { //ä¸ä¸ºç©º 1256 tocContent = mainToc.cloneNode(true); //å¤å¶ 1257 moUserOption.style.display = "none"; //éèç¨æ·æ å¹¶æ¾ç¤ºç®å½ 1258 headToc.style.display = ""; 1259 1260 tocContent.querySelectorAll("li").forEach(li => { //éåå±çº§ 1261 let subol = li.querySelector("ol") 1262 if (subol) { 1263 //å«åç®å½ 1264 li.classList.add("have-child"); 1265 1266 subol.classList.remove('is-collapsible'); 1267 subol.classList.remove('is-collapsed'); 1268 } 1269 }); 1270 1271 tocContent.className = "mo-toc-content"; 1272 tocContent.removeAttribute("style"); 1273 headToc.innerHTML = ""; //æ¸ ç©ºç®æ 容å¨ï¼é²æ¢éå¤ 1274 headToc.appendChild(tocContent); 1275 let activeli = headToc.querySelector(".is-active-li") || headToc.querySelector("li"); //æ»å¨è³tocbotçé«äº®è¿åº¦ 1276 if (activeli) { 1277 activeli.scrollIntoView({ block: "center" }); 1278 } 1279 } else { //ç®å½ä¸ºç©º 1280 if (headToc) { 1281 headToc.style.display = "none"; //éèç®å½ 1282 } 1283 moUserOption.style.display = ""; //å±ç¤ºç¨æ·æ 1284 } 1285 } else { //没æç®å½ 1286 if (headToc) { 1287 headToc.style.display = "none"; 1288 } 1289 moUserOption.style.display = ""; 1290 } 1291 } 1292 1293 //äºçº§èå 1294 document.querySelectorAll(".open_submenu").forEach(function (toggle) { 1295 toggle.addEventListener("click", function (event) { 1296 event.stopPropagation(); 1297 1298 let parentLi = this.closest("li"); 1299 let currentSubMenu = parentLi.querySelector(".sub-menu"); 1300 1301 //äºæ¥ 1302 document.querySelectorAll(".sub-menu.open").forEach(otherSubMenu => { 1303 if (otherSubMenu !== currentSubMenu) { 1304 otherSubMenu.classList.remove("open"); 1305 let otherToggle = otherSubMenu.closest("li").querySelector(".open_submenu"); 1306 if (otherToggle) { 1307 otherToggle.classList.remove("open"); 1308 } 1309 } 1310 }); 1311 1312 if (currentSubMenu) { 1313 currentSubMenu.classList.toggle("open"); 1314 this.classList.toggle("open"); 1315 } 1316 }); 1317 }); 1318 1319 // ç¹å»éé¡¹å ³é 1320 document.querySelectorAll(".mobile-nav a, .mo_toc_panel a").forEach(link => { 1321 link.addEventListener("click", () => { 1322 closeMenu(moNavMenu, moNavButton); 1323 closeMenu(moTocMenu, moTocButton); 1324 }); 1325 }); 1326 1327 // ç¹å»ç©ºç½å¤å ³é 1328 document.addEventListener("click", function (event) { 1329 let navButton = document.querySelector(".mo-nav-button"); 1330 let tocButton = document.querySelector(".mo-toc-button"); 1331 1332 if ( 1333 moNavMenu.classList.contains("open") && 1334 !moNavMenu.contains(event.target) && 1335 !navButton.contains(event.target) 1336 ) { 1337 closeMenu(moNavMenu, navButton,false); 1338 1339 moNavMenu.removeEventListener("transitionend", panelOrderAnime); 1340 moTocMenu.removeEventListener("transitionend", panelOrderAnime); 1341 activeAllButton(); 1342 } 1343 1344 if ( 1345 moTocMenu.classList.contains("open") && 1346 !moTocMenu.contains(event.target) && 1347 !tocButton.contains(event.target) 1348 ) { 1349 closeMenu(moTocMenu, tocButton,false); 1350 1351 moNavMenu.removeEventListener("transitionend", panelOrderAnime); 1352 moTocMenu.removeEventListener("transitionend", panelOrderAnime); 1353 activeAllButton(); 1354 } 1355 1356 if ( 1357 !moNavMenu.contains(event.target) && 1358 !moTocMenu.contains(event.target) && 1359 !navButton.contains(event.target) && 1360 !tocButton.contains(event.target) 1361 ) { 1362 moNavMenu.classList.remove("open"); 1363 moTocMenu.classList.remove("open"); 1364 navButton.classList.remove("open"); 1365 tocButton.classList.remove("open"); 1366 moHeader.removeEventListener("transitionend", navTransitionHandler); 1367 moNavMenu.removeEventListener("transitionend", panelTransitionHandler); 1368 moTocMenu.removeEventListener("transitionend", panelTransitionHandler); 1369 navTransitionHandler = null; 1370 panelTransitionHandler = null; 1371 1372 moNavMenu.removeEventListener("transitionend", panelOrderAnime); 1373 moTocMenu.removeEventListener("transitionend", panelOrderAnime); 1374 activeAllButton(); 1375 } 1376 1377 // å ³éææå±å¼çäºçº§èå 1378 document.querySelectorAll(".sub-menu.open").forEach(function (subMenu) { 1379 if (!subMenu.contains(event.target)) { 1380 subMenu.classList.remove("open"); 1381 let submenuToggle = subMenu.closest("li").querySelector(".open_submenu"); 1382 if (submenuToggle) { 1383 submenuToggle.classList.remove("open"); 1384 } 1385 } 1386 }); 1387 }); 1388 1389 //èªå¨æ¶èµ·æç´¢çé¢ 1390 let moSearchInput = document.querySelector(".mo-menu-search .search-input"); 1391 if (moSearchInput) { 1392 function moSearchClose () { 1393 moSearchInput.blur(); 1394 closeMenu(moNavMenu, moNavButton); 1395 } 1396 moSearchInput.addEventListener("focus", function() { 1397 document.addEventListener('pjax:complete', moSearchClose); 1398 }); 1399 moSearchInput.addEventListener("blur", function() { 1400 document.removeEventListener("pjax:complete", moSearchClose); 1401 }); 1402 } 1403 1404 //ä¸é¢æ¯èªå¨æ¶èµ·ãå±å¼å¯¼èªæ é¨å 1405 let lastScrollTop = 0; 1406 // éå¼ 1407 const scrollThreshold = document.documentElement.scrollHeight * 0.01; 1408 1409 // æ»å¨æ¢å¤æ£æµ 1410 let isRestoringScroll = false;
1411 window.addEventListener('scroll', function restoreScrollCheck() { 1412 if (!isRestoringScroll && (window.pageYOffset > 0)) { 1413 isRestoringScroll = true; 1414 setTimeout(() => { 1415 if (window._searchWrapperState) { 1416 window._searchWrapperState.handleScroll(); 1417 window._searchWrapperState.show(); // 强å¶éç®å®½åº¦ 1418 } 1419 }, 100); 1420 window.removeEventListener('scroll', restoreScrollCheck); 1421 } 1422 }, { passive: true }); 1423 1424 window.addEventListener("scroll", function () { 1425 1426 if (window.innerWidth < 860) { 1427 1428 let moScrollTop = window.scrollY || document.documentElement.scrollTop; 1429 1430 if (moScrollTop > scrollThreshold) { 1431 if (moScrollTop > lastScrollTop) { 1432 // å䏿»å¨ 1433 if (navTransitionHandler) { 1434 moHeader.removeEventListener("transitionend", navTransitionHandler); 1435 navTransitionHandler = null; 1436 } 1437 1438 if (panelTransitionHandler) { 1439 moNavMenu.removeEventListener("transitionend", panelTransitionHandler); 1440 moTocMenu.removeEventListener("transitionend", panelTransitionHandler); 1441 panelTransitionHandler = null; 1442 } 1443 1444 moHeader.classList.add("mo-hide"); 1445 moHeader.classList.remove("bg"); 1446 moNavMenu.classList.remove("open"); 1447 moNavButton.classList.remove("open"); 1448 moTocMenu.classList.remove("open"); 1449 moTocButton.classList.remove("open"); 1450 1451 moNavMenu.removeEventListener("transitionend", panelOrderAnime); //ç§»é¤å¨ç»çå¬å¹¶éæ°æ¿æ´»æé® 1452 moTocMenu.removeEventListener("transitionend", panelOrderAnime); 1453 activeAllButton(); 1454 1455 // åæ¶å ³éææå±å¼çäºçº§èå 1456 document.querySelectorAll(".mobile-nav .sub-menu.open").forEach(function (subMenu) { 1457 subMenu.classList.remove("open"); 1458 }); 1459 document.querySelectorAll(".mobile-nav .open_submenu.open").forEach(function (toggle) { 1460 toggle.classList.remove("open"); 1461 }); 1462 } else { 1463 // å䏿»å¨ 1464 moHeader.classList.remove("mo-hide"); 1465 moHeader.classList.add("bg"); 1466 } 1467 } else { 1468 // æ»å¨è·ç¦»å°äºéå¼ 1469 moHeader.classList.remove("mo-hide"); 1470 } 1471 if (moScrollTop <= 0 && !isAnyPanelOpen()) { 1472 moHeader.classList.remove("bg"); 1473 } 1474 1475 lastScrollTop = moScrollTop; 1476 } 1477 }); 1478 moHeader.classList.remove("bg"); 1479});
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.