mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-18 03:00:58 +08:00
scroll end timing
This commit is contained in:
@ -71,18 +71,18 @@ export class SegmentView implements ComponentInterface {
|
||||
// Find the current segment content based on the scroll position
|
||||
const currentIndex = Math.round(scrollLeft / offsetWidth);
|
||||
|
||||
// Recursively search for the next enabled content in the scroll direction
|
||||
const segmentContent = this.getNextEnabledContent(currentIndex, scrollDirection);
|
||||
// // Update active content ID and scroll to the segment content
|
||||
const activeContent = this.getSegmentContents().filter(
|
||||
(ref) => !ref.classList.contains('segment-content-disabled')
|
||||
)[currentIndex];
|
||||
this.activeContentId = activeContent.id;
|
||||
|
||||
// Exit if no valid segment content found
|
||||
if (!segmentContent) return;
|
||||
|
||||
// Update active content ID and scroll to the segment content
|
||||
this.activeContentId = segmentContent.id;
|
||||
this.setContent(segmentContent.id);
|
||||
|
||||
// Reset the timeout to check for scroll end
|
||||
this.resetScrollEndTimeout();
|
||||
// Only emit scroll end event if the active content is not disabled and
|
||||
// the user is not touching the segment view
|
||||
if (activeContent?.disabled === false && !this.isTouching) {
|
||||
this.ionSegmentViewScrollEnd.emit({ activeContentId: this.activeContentId });
|
||||
this.initialScrollLeft = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -108,35 +108,6 @@ export class SegmentView implements ComponentInterface {
|
||||
this.isTouching = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the scroll end detection timer. This is called on every scroll event.
|
||||
*/
|
||||
private resetScrollEndTimeout() {
|
||||
if (this.scrollEndTimeout) {
|
||||
clearTimeout(this.scrollEndTimeout);
|
||||
this.scrollEndTimeout = null;
|
||||
}
|
||||
this.scrollEndTimeout = setTimeout(() => {
|
||||
this.checkForScrollEnd();
|
||||
}, 150);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the scroll has ended and the user is not actively touching.
|
||||
* If the conditions are met (active content is enabled and no active touch),
|
||||
* reset the scroll position and emit the scroll end event.
|
||||
*/
|
||||
private checkForScrollEnd() {
|
||||
const activeContent = this.getSegmentContents().find((content) => content.id === this.activeContentId);
|
||||
|
||||
// Only emit scroll end event if the active content is not disabled and
|
||||
// the user is not touching the segment view
|
||||
if (activeContent?.disabled === false && !this.isTouching) {
|
||||
this.ionSegmentViewScrollEnd.emit({ activeContentId: this.activeContentId });
|
||||
this.initialScrollLeft = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to programmatically set the displayed segment content
|
||||
* in the segment view. Calling this method will update the `value` of the
|
||||
|
@ -28,8 +28,6 @@ export class Segment implements ComponentInterface {
|
||||
private valueBeforeGesture?: SegmentValue;
|
||||
|
||||
private segmentViewEl?: HTMLIonSegmentViewElement | null = null;
|
||||
private scrolledIndicator?: HTMLDivElement | null = null;
|
||||
private isScrolling = false;
|
||||
|
||||
@Element() el!: HTMLIonSegmentElement;
|
||||
|
||||
@ -381,10 +379,6 @@ export class Segment implements ComponentInterface {
|
||||
|
||||
@Listen('ionSegmentViewScroll', { target: 'body' })
|
||||
handleSegmentViewScroll(ev: CustomEvent) {
|
||||
if (!this.isScrolling) {
|
||||
return;
|
||||
}
|
||||
|
||||
const dispatchedFrom = ev.target as HTMLElement;
|
||||
const segmentViewEl = this.segmentViewEl as EventTarget;
|
||||
const segmentEl = this.el;
|
||||
@ -464,6 +458,7 @@ export class Segment implements ComponentInterface {
|
||||
indicator.querySelector('div')!.style.backgroundColor = color;
|
||||
}
|
||||
|
||||
// Scroll the segment container if the indicator is out of view
|
||||
const indicatorX = indicator.getBoundingClientRect().x;
|
||||
if (scrollDistance < 0 && indicatorX < 0) {
|
||||
this.el.scrollBy({
|
||||
@ -482,17 +477,6 @@ export class Segment implements ComponentInterface {
|
||||
}
|
||||
}
|
||||
|
||||
@Listen('ionSegmentViewScrollStart', { target: 'body' })
|
||||
onScrollStart(ev: CustomEvent) {
|
||||
const dispatchedFrom = ev.target as HTMLElement;
|
||||
const segmentViewEl = this.segmentViewEl as EventTarget;
|
||||
const segmentEl = this.el;
|
||||
|
||||
if (ev.composedPath().includes(segmentViewEl) || dispatchedFrom?.contains(segmentEl)) {
|
||||
this.isScrolling = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Listen('ionSegmentViewScrollEnd', { target: 'body' })
|
||||
onScrollEnd(ev: CustomEvent<{ activeContentId: string }>) {
|
||||
const dispatchedFrom = ev.target as HTMLElement;
|
||||
@ -500,31 +484,10 @@ export class Segment implements ComponentInterface {
|
||||
const segmentEl = this.el;
|
||||
|
||||
if (ev.composedPath().includes(segmentViewEl) || dispatchedFrom?.contains(segmentEl)) {
|
||||
this.isScrolling = false;
|
||||
|
||||
this.value = ev.detail.activeContentId;
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for the transition to end, then execute the callback
|
||||
private waitForTransitionEnd(indicator: HTMLElement, callback: () => void) {
|
||||
const onTransitionEnd = () => {
|
||||
indicator.removeEventListener('transitionend', onTransitionEnd);
|
||||
callback();
|
||||
};
|
||||
indicator.addEventListener('transitionend', onTransitionEnd);
|
||||
}
|
||||
|
||||
// Update the Segment value after the ionSegmentViewScrollEnd transition has ended
|
||||
private updateValueAfterTransition(activeContentId: string) {
|
||||
this.value = activeContentId;
|
||||
|
||||
if (this.scrolledIndicator) {
|
||||
this.scrolledIndicator.style.transition = '';
|
||||
this.scrolledIndicator.style.transform = '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the related segment view and sets its current content
|
||||
* based on the selected segment button. This method
|
||||
|
Reference in New Issue
Block a user