@@ -182,15 +182,58 @@ export default {
182182 this ._menuEl = menuEl
183183 this ._onMenuOver = this .handleMenuMouseOver .bind (this )
184184 this ._onMenuLeave = this .handleMenuMouseLeave .bind (this )
185- this ._onWindowResize = () => this .moveIndicatorToActive ()
185+ this ._onWindowResize = () => this .scheduleIndicatorUpdate ()
186+ this ._onWindowLoad = () => this .scheduleIndicatorUpdate ()
186187 menuEl .addEventListener (" mouseover" , this ._onMenuOver )
187188 menuEl .addEventListener (" mouseleave" , this ._onMenuLeave )
188189 window .addEventListener (" resize" , this ._onWindowResize )
189- this .moveIndicatorToActive ()
190- requestAnimationFrame (() => {
190+ window .addEventListener (" load" , this ._onWindowLoad )
191+ this .observeIndicatorLayout (menuEl)
192+ this .scheduleIndicatorUpdate ()
193+ this .showIndicatorWhenLayoutReady ()
194+ },
195+ observeIndicatorLayout (menuEl ) {
196+ if (window .ResizeObserver ) {
197+ this ._indicatorResizeObserver = new ResizeObserver (() => {
198+ this .scheduleIndicatorUpdate ()
199+ })
200+ this ._indicatorResizeObserver .observe (menuEl)
201+ this ._indicatorResizeObserver .observe (this .$el )
202+ }
203+
204+ this ._indicatorImages = Array .prototype .slice .call (
205+ menuEl .querySelectorAll (" img" ),
206+ )
207+ this ._onIndicatorAssetLoad = () => this .scheduleIndicatorUpdate ()
208+ this ._indicatorImages .forEach ((img ) => {
209+ if (img .complete ) return
210+ img .addEventListener (" load" , this ._onIndicatorAssetLoad )
211+ img .addEventListener (" error" , this ._onIndicatorAssetLoad )
212+ })
213+ },
214+ showIndicatorWhenLayoutReady () {
215+ const showIndicator = () => {
216+ this .scheduleIndicatorUpdate ()
191217 requestAnimationFrame (() => {
192- this .indicatorReady = true
218+ requestAnimationFrame (() => {
219+ if (this ._menuEl ) this .indicatorReady = true
220+ })
193221 })
222+ }
223+
224+ if (document .fonts && document .fonts .ready ) {
225+ document .fonts .ready .then (showIndicator)
226+ } else {
227+ showIndicator ()
228+ }
229+ },
230+ scheduleIndicatorUpdate () {
231+ if (this ._indicatorFrame ) {
232+ cancelAnimationFrame (this ._indicatorFrame )
233+ }
234+ this ._indicatorFrame = requestAnimationFrame (() => {
235+ this ._indicatorFrame = null
236+ this .moveIndicatorToActive ()
194237 })
195238 },
196239 teardownIndicator () {
@@ -201,10 +244,30 @@ export default {
201244 if (this ._onWindowResize ) {
202245 window .removeEventListener (" resize" , this ._onWindowResize )
203246 }
247+ if (this ._onWindowLoad ) {
248+ window .removeEventListener (" load" , this ._onWindowLoad )
249+ }
250+ if (this ._indicatorResizeObserver ) {
251+ this ._indicatorResizeObserver .disconnect ()
252+ }
253+ if (this ._indicatorImages && this ._onIndicatorAssetLoad ) {
254+ this ._indicatorImages .forEach ((img ) => {
255+ img .removeEventListener (" load" , this ._onIndicatorAssetLoad )
256+ img .removeEventListener (" error" , this ._onIndicatorAssetLoad )
257+ })
258+ }
259+ if (this ._indicatorFrame ) {
260+ cancelAnimationFrame (this ._indicatorFrame )
261+ }
204262 this ._menuEl = null
205263 this ._onMenuOver = null
206264 this ._onMenuLeave = null
207265 this ._onWindowResize = null
266+ this ._onWindowLoad = null
267+ this ._indicatorResizeObserver = null
268+ this ._indicatorImages = null
269+ this ._onIndicatorAssetLoad = null
270+ this ._indicatorFrame = null
208271 },
209272 handleMenuMouseOver (e ) {
210273 if (! this ._menuEl ) return
@@ -267,7 +330,7 @@ export default {
267330 },
268331 watch: {
269332 activeMenu () {
270- this .$nextTick (() => this .moveIndicatorToActive ())
333+ this .$nextTick (() => this .scheduleIndicatorUpdate ())
271334 },
272335 },
273336}
0 commit comments