|
1 | | -import { isIonContent, findClosestIonContent } from '@utils/content'; |
| 1 | +import { findClosestIonContent, isIonContent } from '@utils/content'; |
2 | 2 | import { createGesture } from '@utils/gesture'; |
3 | | -import { clamp, raf, getElementRoot } from '@utils/helpers'; |
| 3 | +import { clamp, getElementRoot, raf } from '@utils/helpers'; |
4 | 4 | import { FOCUS_TRAP_DISABLE_CLASS } from '@utils/overlays'; |
5 | 5 |
|
6 | 6 | import type { Animation } from '../../../interface'; |
@@ -84,6 +84,7 @@ export const createSheetGesture = ( |
84 | 84 | let currentBreakpoint = initialBreakpoint; |
85 | 85 | let offset = 0; |
86 | 86 | let canDismissBlocksGesture = false; |
| 87 | + let cachedScrollEl: HTMLElement | null = null; |
87 | 88 | const canDismissMaxStep = 0.95; |
88 | 89 | const maxBreakpoint = breakpoints[breakpoints.length - 1]; |
89 | 90 | const minBreakpoint = breakpoints[0]; |
@@ -234,6 +235,17 @@ export const createSheetGesture = ( |
234 | 235 | */ |
235 | 236 | canDismissBlocksGesture = baseEl.canDismiss !== undefined && baseEl.canDismiss !== true && minBreakpoint === 0; |
236 | 237 |
|
| 238 | + /** |
| 239 | + * Cache the scroll element reference when the gesture starts, |
| 240 | + * this allows us to avoid querying the DOM for the target in onMove, |
| 241 | + * which would impact performance significantly. |
| 242 | + */ |
| 243 | + if (!expandToScroll) { |
| 244 | + const targetEl = findClosestIonContent(detail.event.target! as HTMLElement); |
| 245 | + cachedScrollEl = |
| 246 | + targetEl && isIonContent(targetEl) ? getElementRoot(targetEl).querySelector('.inner-scroll') : targetEl; |
| 247 | + } |
| 248 | + |
237 | 249 | /** |
238 | 250 | * If expandToScroll is disabled, we need to swap |
239 | 251 | * the footer visibility to the original, so if the modal |
@@ -268,13 +280,8 @@ export const createSheetGesture = ( |
268 | 280 | * If `expandToScroll` is disabled, and an upwards swipe gesture is done within |
269 | 281 | * the scrollable content, we should not allow the swipe gesture to continue. |
270 | 282 | */ |
271 | | - if (!expandToScroll && detail.deltaY <= 0) { |
272 | | - const contentEl = findClosestIonContent(detail.event.target! as HTMLElement); |
273 | | - const scrollEl = |
274 | | - contentEl && isIonContent(contentEl) ? getElementRoot(contentEl).querySelector('.inner-scroll') : contentEl; |
275 | | - if (scrollEl) { |
276 | | - return; |
277 | | - } |
| 283 | + if (!expandToScroll && detail.deltaY <= 0 && cachedScrollEl) { |
| 284 | + return; |
278 | 285 | } |
279 | 286 |
|
280 | 287 | /** |
@@ -335,12 +342,8 @@ export const createSheetGesture = ( |
335 | 342 | * function to be called if the user is trying to swipe content upwards and the content |
336 | 343 | * is not scrolled to the top. |
337 | 344 | */ |
338 | | - if (!expandToScroll && detail.deltaY <= 0 && findClosestIonContent(detail.event.target! as HTMLElement)) { |
339 | | - const contentEl = findClosestIonContent(detail.event.target! as HTMLElement)!; |
340 | | - const scrollEl = isIonContent(contentEl) ? getElementRoot(contentEl).querySelector('.inner-scroll') : contentEl; |
341 | | - if (scrollEl!.scrollTop > 0) { |
342 | | - return; |
343 | | - } |
| 345 | + if (!expandToScroll && detail.deltaY <= 0 && cachedScrollEl && cachedScrollEl.scrollTop > 0) { |
| 346 | + return; |
344 | 347 | } |
345 | 348 |
|
346 | 349 | /** |
|
0 commit comments