Skip to content

Commit e9d6411

Browse files
committed
Popover: Optimize global events + autoHide no longer blocks event.closePopover
1 parent 3c0cd65 commit e9d6411

File tree

1 file changed

+46
-34
lines changed

1 file changed

+46
-34
lines changed

src/components/Popover.vue

Lines changed: 46 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ if (typeof window !== 'undefined' && typeof navigator !== 'undefined') {
5555
isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream
5656
}
5757
58+
const openPopovers = []
59+
5860
export default {
5961
name: 'VPopover',
6062
@@ -256,9 +258,8 @@ export default {
256258
dispose () {
257259
this.$_isDisposed = true
258260
this.$_removeEventListeners()
259-
this.$_removeGlobalEvents()
261+
this.hide({ skipDelay: true })
260262
if (this.popperInstance) {
261-
this.hide()
262263
this.popperInstance.destroy()
263264
264265
// destroy tooltipNode if removeOnDestroy is not set, as popperInstance.destroy() already removes the element
@@ -294,7 +295,6 @@ export default {
294295
this.isOpen = true
295296
this.popperInstance.enableEventListeners()
296297
this.popperInstance.update()
297-
this.$_addGlobalEvents()
298298
}
299299
300300
if (!this.$_mounted) {
@@ -345,7 +345,6 @@ export default {
345345
requestAnimationFrame(() => {
346346
if (!this.$_isDisposed) {
347347
this.isOpen = true
348-
this.$_addGlobalEvents()
349348
} else {
350349
this.dispose()
351350
}
@@ -355,6 +354,8 @@ export default {
355354
}
356355
})
357356
}
357+
358+
openPopovers.push(this)
358359
},
359360
360361
$_hide () {
@@ -363,9 +364,15 @@ export default {
363364
return
364365
}
365366
367+
const index = openPopovers.indexOf(this)
368+
if (index !== -1) {
369+
openPopovers.splice(index, 1)
370+
}
371+
366372
this.isOpen = false
367-
this.popperInstance.disableEventListeners()
368-
this.$_removeGlobalEvents()
373+
if (this.popperInstance) {
374+
this.popperInstance.disableEventListeners()
375+
}
369376
370377
clearTimeout(this.$_disposeTimer)
371378
const disposeTime = directive.options.popover.disposeTimeout || directive.options.disposeTimeout
@@ -536,26 +543,6 @@ export default {
536543
this.$_events = []
537544
},
538545
539-
$_addGlobalEvents () {
540-
if (this.autoHide) {
541-
if (isIOS) {
542-
document.addEventListener('touchend', this.$_handleWindowTouchstart, supportsPassive ? {
543-
passive: true,
544-
} : false)
545-
} else {
546-
window.addEventListener('click', this.$_handleWindowClick)
547-
}
548-
}
549-
},
550-
551-
$_removeGlobalEvents () {
552-
if (isIOS) {
553-
document.removeEventListener('touchend', this.$_handleWindowTouchstart)
554-
} else {
555-
window.removeEventListener('click', this.$_handleWindowClick)
556-
}
557-
},
558-
559546
$_updatePopper (cb) {
560547
if (this.isOpen && this.popperInstance) {
561548
cb()
@@ -574,12 +561,17 @@ export default {
574561
}
575562
},
576563
577-
$_handleWindowClick (event, touch = false) {
564+
$_handleGlobalClose (event, touch = false) {
578565
const popoverNode = this.$refs.popover
579566
580-
if (event.closePopover || !popoverNode.contains(event.target)) {
581-
this.$_scheduleHide({ event: event })
582-
this.$emit('auto-hide')
567+
if (event.closePopover || (this.autoHide && !popoverNode.contains(event.target))) {
568+
this.hide({ event: event })
569+
570+
if (event.closePopover) {
571+
this.$emit('close-directive')
572+
} else {
573+
this.$emit('auto-hide')
574+
}
583575
584576
if (touch) {
585577
this.$_preventOpen = true
@@ -590,10 +582,6 @@ export default {
590582
}
591583
},
592584
593-
$_handleWindowTouchstart (event) {
594-
this.$_handleWindowClick(event, true)
595-
},
596-
597585
$_handleResize () {
598586
if (this.isOpen && this.popperInstance) {
599587
this.popperInstance.update()
@@ -602,4 +590,28 @@ export default {
602590
},
603591
},
604592
}
593+
594+
if (typeof document !== 'undefined' && typeof window !== 'undefined') {
595+
if (isIOS) {
596+
document.addEventListener('touchend', handleGlobalTouchend, supportsPassive ? {
597+
passive: true,
598+
} : false)
599+
} else {
600+
window.addEventListener('click', handleGlobalClick)
601+
}
602+
}
603+
604+
function handleGlobalClick (event) {
605+
handleGlobalClose(event)
606+
}
607+
608+
function handleGlobalTouchend (event) {
609+
handleGlobalClose(event, true)
610+
}
611+
612+
function handleGlobalClose (event, touch = false) {
613+
for (let i = 0; i < openPopovers.length; i++) {
614+
openPopovers[i].$_handleGlobalClose(event, touch)
615+
}
616+
}
605617
</script>

0 commit comments

Comments
 (0)