@@ -31,6 +31,22 @@ const ScrollbarWrapper = defineComponent(() => {
3131 } ;
3232} ) ;
3333
34+ const isInViewport = ( element : HTMLElement ) : boolean => {
35+ const rect = element . getBoundingClientRect ( ) ;
36+ const offset = window . innerHeight * 0.15 ;
37+ return rect . top - offset >= 0 && rect . bottom + offset <= window . innerHeight ;
38+ } ;
39+
40+ const checkAllImagesLoaded = ( ) => {
41+ const images = document . images ;
42+ for ( let i = 0 ; i < images . length ; i ++ ) {
43+ if ( ! images [ i ] . complete ) {
44+ return false ;
45+ }
46+ }
47+ return true ;
48+ } ;
49+
3450const handleCompatRedirect = async ( router : Router ) => {
3551 // 兼容旧链接/短链重定向
3652 const u = location . href . substring ( location . origin . length ) ;
@@ -83,9 +99,19 @@ const handleCompatRedirect = async (router: Router) => {
8399 }
84100 } ) ( ) ;
85101 if ( hashEl ) {
102+ if ( ! isInViewport ( hashEl ) ) {
103+ // 图片加载完成会导致排版变化,此处手动判断后滚动到视口中
104+ // 也许后续可实现在构建时提前获取 size 后设置 aspect-ratio
105+ let i = 0 ;
106+ while ( i < 25 && ! checkAllImagesLoaded ( ) ) {
107+ await new Promise ( ( r ) => setTimeout ( r , 100 ) ) ;
108+ i ++ ;
109+ }
110+ hashEl . scrollIntoView ( { behavior : 'smooth' , block : 'center' } ) ;
111+ }
86112 const hintCls = 'animate-hash-hint' ;
87113 hashEl . classList . add ( hintCls ) ;
88- await new Promise ( ( r ) => setTimeout ( r , 3000 ) ) ;
114+ await new Promise ( ( r ) => setTimeout ( r , 500 * 2 * 5 ) ) ;
89115 hashEl . classList . remove ( hintCls ) ;
90116 }
91117 }
0 commit comments