Skip to content

Commit

Permalink
fix: don't compute position on scroll if hidden, closes #835
Browse files Browse the repository at this point in the history
  • Loading branch information
Akryum committed Mar 11, 2022
1 parent fcd9f0b commit f2199da
Showing 1 changed file with 48 additions and 40 deletions.
88 changes: 48 additions & 40 deletions packages/floating-vue/src/components/Popper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,16 @@ export default () => ({
await nextFrame()
await this.$_computePosition()
await this.$_applyShowEffect()

// Scroll
if (!this.positioningDisabled) {
this.$_registerEventListeners([
...getScrollParents(this.$_referenceNode),
...getScrollParents(this.$_popperNode),
], 'scroll', () => {
this.$_computePosition()
})
}
},

async $_applyShowEffect () {
Expand Down Expand Up @@ -682,6 +692,8 @@ export default () => ({
}, disposeTime)
}

this.$_removeEventListeners('scroll')

this.$emit('apply-hide')

// Advanced classes
Expand Down Expand Up @@ -723,30 +735,6 @@ export default () => ({
},

$_addEventListeners () {
const addListeners = (targetNodes: any[], eventType: string, handler: (event: Event) => void) => {
this.$_events.push({ targetNodes, eventType, handler })
targetNodes.forEach(node => node.addEventListener(eventType, handler, supportsPassive
? {
passive: true,
}
: undefined))
}

const addEvents = (targetNodes, eventMap, commonTriggers, customTrigger, handler) => {
let triggers = commonTriggers

if (customTrigger != null) {
triggers = typeof customTrigger === 'function' ? customTrigger(triggers) : customTrigger
}

triggers.forEach(trigger => {
const eventType = eventMap[trigger]
if (eventType) {
addListeners(targetNodes, eventType, handler)
}
})
}

// Add trigger show events

const handleShow = event => {
Expand All @@ -758,8 +746,8 @@ export default () => ({
!this.$_preventShow && this.show({ event })
}

addEvents(this.$_targetNodes, SHOW_EVENT_MAP, this.triggers, this.showTriggers, handleShow)
addEvents([this.$_popperNode], SHOW_EVENT_MAP, this.popperTriggers, this.popperShowTriggers, handleShow)
this.$_registerTriggerListeners(this.$_targetNodes, SHOW_EVENT_MAP, this.triggers, this.showTriggers, handleShow)
this.$_registerTriggerListeners([this.$_popperNode], SHOW_EVENT_MAP, this.popperTriggers, this.popperShowTriggers, handleShow)

// Add trigger hide events

Expand All @@ -770,25 +758,45 @@ export default () => ({
this.hide({ event })
}

addEvents(this.$_targetNodes, HIDE_EVENT_MAP, this.triggers, this.hideTriggers, handleHide)
addEvents([this.$_popperNode], HIDE_EVENT_MAP, this.popperTriggers, this.popperHideTriggers, handleHide)
this.$_registerTriggerListeners(this.$_targetNodes, HIDE_EVENT_MAP, this.triggers, this.hideTriggers, handleHide)
this.$_registerTriggerListeners([this.$_popperNode], HIDE_EVENT_MAP, this.popperTriggers, this.popperHideTriggers, handleHide)
},

// Scroll
if (!this.positioningDisabled) {
addListeners([
...getScrollParents(this.$_referenceNode),
...getScrollParents(this.$_popperNode),
], 'scroll', () => {
this.$_computePosition()
})
$_registerEventListeners (targetNodes: any[], eventType: string, handler: (event: Event) => void) {
this.$_events.push({ targetNodes, eventType, handler })
targetNodes.forEach(node => node.addEventListener(eventType, handler, supportsPassive
? {
passive: true,
}
: undefined))
},

$_registerTriggerListeners (targetNodes: any[], eventMap: Record<string, string>, commonTriggers, customTrigger, handler: (event: Event) => void) {
let triggers = commonTriggers

if (customTrigger != null) {
triggers = typeof customTrigger === 'function' ? customTrigger(triggers) : customTrigger
}

triggers.forEach(trigger => {
const eventType = eventMap[trigger]
if (eventType) {
this.$_registerEventListeners(targetNodes, eventType, handler)
}
})
},

$_removeEventListeners () {
this.$_events.forEach(({ targetNodes, eventType, handler }) => {
targetNodes.forEach(node => node.removeEventListener(eventType, handler))
$_removeEventListeners (filterEventType?: string) {
const newList = []
this.$_events.forEach(listener => {
const { targetNodes, eventType, handler } = listener
if (!filterEventType || filterEventType === eventType) {
targetNodes.forEach(node => node.removeEventListener(eventType, handler))
} else {
newList.push(listener)
}
})
this.$_events = []
this.$_events = newList
},

$_refreshListeners () {
Expand Down

0 comments on commit f2199da

Please sign in to comment.