@@ -109,7 +109,11 @@ const PageLoader = {
109109 el : null ,
110110 startTime : null ,
111111 minDuration : 500 ,
112+ closeDuration : 200 ,
113+ minCloseProgress : 160 ,
114+ phase : "closed" ,
112115 _hideTimerId : null ,
116+ _closeTimerId : null ,
113117
114118 getEl ( ) {
115119 if ( ! this . el ) {
@@ -124,14 +128,33 @@ const PageLoader = {
124128 clearTimeout ( this . _hideTimerId ) ;
125129 this . _hideTimerId = null ;
126130 }
131+ if ( this . _closeTimerId ) {
132+ clearTimeout ( this . _closeTimerId ) ;
133+ this . _closeTimerId = null ;
134+ }
127135 this . startTime = Date . now ( ) ;
136+ this . phase = "closing" ;
128137 var el = this . getEl ( ) ;
129138 if ( el ) {
130139 el . classList . remove ( "loading" ) ;
131140 }
141+
142+ var self = this ;
143+ this . _closeTimerId = setTimeout ( function ( ) {
144+ self . _closeTimerId = null ;
145+ if ( self . phase === "closing" ) {
146+ self . phase = "closed" ;
147+ }
148+ } , this . closeDuration ) ;
132149 } ,
133150
134151 hide ( ) {
152+ if ( this . _closeTimerId ) {
153+ clearTimeout ( this . _closeTimerId ) ;
154+ this . _closeTimerId = null ;
155+ }
156+ this . startTime = null ;
157+ this . phase = "opened" ;
135158 document . body . style . overflow = "auto" ;
136159 var el = this . getEl ( ) ;
137160 if ( el ) {
@@ -141,7 +164,7 @@ const PageLoader = {
141164
142165 end ( ) {
143166 // 如果已经有延迟隐藏在进行中,不重复处理
144- if ( this . _hideTimerId ) {
167+ if ( this . _hideTimerId && this . phase !== "closing" ) {
145168 return ;
146169 }
147170
@@ -150,16 +173,33 @@ const PageLoader = {
150173 return ;
151174 }
152175
176+ // 关门中已经加载完成:从当前位置反向开门
177+ if ( this . phase === "closing" ) {
178+ var closingElapsed = Date . now ( ) - this . startTime ;
179+ if ( closingElapsed >= this . minCloseProgress ) {
180+ this . hide ( ) ;
181+ } else {
182+ var self = this ;
183+ this . _hideTimerId = setTimeout ( function ( ) {
184+ self . _hideTimerId = null ;
185+ // 若期间又进入了新的 start,不执行本次开门
186+ if ( self . phase === "closing" ) {
187+ self . hide ( ) ;
188+ }
189+ } , this . minCloseProgress - closingElapsed ) ;
190+ }
191+ return ;
192+ }
193+
153194 var elapsed = Date . now ( ) - this . startTime ;
154- this . startTime = null ;
155195
156196 if ( elapsed >= this . minDuration ) {
157197 this . hide ( ) ;
158198 } else {
159199 // 延迟到最小持续时间后再隐藏
160200 var remaining = this . minDuration - elapsed ;
161201 var self = this ;
162- this . _hideTimerId = setTimeout ( function ( ) {
202+ this . _hideTimerId = setTimeout ( function ( ) {
163203 self . _hideTimerId = null ;
164204 self . hide ( ) ;
165205 } , remaining ) ;
@@ -172,7 +212,7 @@ function startLoading() { PageLoader.start(); }
172212function endLoading ( ) { PageLoader . end ( ) ; }
173213
174214// 初始化 loader 点击事件
175- ( function ( ) {
215+ ( function ( ) {
176216 var el = document . getElementById ( "loader" ) ;
177217 if ( el ) {
178218 el . addEventListener ( "click" , endLoading ) ;
@@ -254,12 +294,12 @@ function initLozad() {
254294 */
255295function initMediumZoom ( ) {
256296 if ( typeof mediumZoom === "undefined" ) return ;
257-
297+
258298 // 销毁之前的实例(如果存在)
259299 if ( window . _mediumZoomInstance ) {
260300 window . _mediumZoomInstance . detach ( ) ;
261301 }
262-
302+
263303 // 创建新实例
264304 window . _mediumZoomInstance = mediumZoom ( "[data-zoomable]" , {
265305 margin : 24 ,
@@ -304,20 +344,20 @@ const Navigation = {
304344 // 使用 data 属性标记是否已绑定事件,避免重复绑定
305345 if ( ! this . menuToggle . _navBound ) {
306346 var self = this ;
307- this . menuToggle . addEventListener ( "click" , function ( ) { self . toggle ( ) ; } ) ;
347+ this . menuToggle . addEventListener ( "click" , function ( ) { self . toggle ( ) ; } ) ;
308348 this . menuToggle . _navBound = true ;
309349 }
310-
350+
311351 // scroll 和 keydown 事件只需要绑定一次
312352 if ( ! this . _scrollInitialized ) {
313353 var self = this ;
314- window . addEventListener ( "scroll" , function ( ) { self . handleScroll ( ) ; } , { passive : true } ) ;
315-
354+ window . addEventListener ( "scroll" , function ( ) { self . handleScroll ( ) ; } , { passive : true } ) ;
355+
316356 // ESC 键关闭菜单
317- document . addEventListener ( "keydown" , function ( e ) {
357+ document . addEventListener ( "keydown" , function ( e ) {
318358 if ( e . key === "Escape" && self . isOpen ) self . close ( ) ;
319359 } ) ;
320-
360+
321361 this . _scrollInitialized = true ;
322362 }
323363 } ,
@@ -391,13 +431,13 @@ function initSearch() {
391431 showSubResults : true ,
392432 resetStyles : false ,
393433 } ) ;
394-
434+
395435 // 支持 URL 参数直接搜索,如 /search/?q=keyword
396436 var urlParams = new URLSearchParams ( window . location . search ) ;
397437 var query = urlParams . get ( "q" ) ;
398438 if ( query ) {
399439 // 延迟确保 PagefindUI 完全初始化
400- setTimeout ( function ( ) {
440+ setTimeout ( function ( ) {
401441 var searchInput = searchContainer . querySelector ( ".pagefind-ui__search-input" ) ;
402442 if ( searchInput ) {
403443 searchInput . value = query ;
0 commit comments