MOBILE-3814 dom: Fix scroll to element with selector
parent
be28e1c2e4
commit
ac5e4b1d79
|
@ -514,6 +514,7 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
|
|||
CoreDomUtils.scrollViewToElement(
|
||||
this.elementRef.nativeElement,
|
||||
'#core-course-module-' + moduleId,
|
||||
{ addYAxis: -10 },
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -112,6 +112,7 @@ export class CoreCourseCourseIndexComponent implements OnInit {
|
|||
CoreDomUtils.scrollViewToElement(
|
||||
this.elementRef.nativeElement,
|
||||
'.item.item-current',
|
||||
{ addYAxis: -10 },
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ export class CoreDomUtilsProvider {
|
|||
}
|
||||
|
||||
/**
|
||||
* Wait an element to be in dom of another element.
|
||||
* Wait an element to be added to the root DOM.
|
||||
*
|
||||
* @param element Element to wait.
|
||||
* @return Cancellable promise.
|
||||
|
@ -130,6 +130,44 @@ export class CoreDomUtilsProvider {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait an element to be in dom of another element using a selector
|
||||
*
|
||||
* @param container Element to wait.
|
||||
* @return Cancellable promise.
|
||||
*/
|
||||
async waitToBeInsideElement(container: HTMLElement, selector: string): Promise<CoreCancellablePromise<HTMLElement>> {
|
||||
await CoreDomUtils.waitToBeInDOM(container);
|
||||
|
||||
let element = container.querySelector<HTMLElement>(selector);
|
||||
if (element) {
|
||||
// Already in DOM.
|
||||
return CoreCancellablePromise.resolve(element);
|
||||
}
|
||||
|
||||
let observer: MutationObserver;
|
||||
|
||||
return new CoreCancellablePromise<HTMLElement>(
|
||||
(resolve) => {
|
||||
observer = new MutationObserver(() => {
|
||||
element = container.querySelector<HTMLElement>(selector);
|
||||
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
|
||||
observer?.disconnect();
|
||||
resolve(element);
|
||||
});
|
||||
|
||||
observer.observe(container, { subtree: true, childList: true });
|
||||
},
|
||||
() => {
|
||||
observer?.disconnect();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait an element to be in dom and visible.
|
||||
*
|
||||
|
@ -889,7 +927,7 @@ export class CoreDomUtilsProvider {
|
|||
*
|
||||
* @param findFunction The function used to find the element.
|
||||
* @return Resolved if found, rejected if too many tries.
|
||||
* @deprecated since app 4.0 Use waitToBeInDOM instead.
|
||||
* @deprecated since app 4.0 Use waitToBeInsideElement instead.
|
||||
*/
|
||||
waitElementToExist(findFunction: () => HTMLElement | null): Promise<HTMLElement> {
|
||||
const promiseInterval = CoreUtils.promiseDefer<HTMLElement>();
|
||||
|
@ -1320,14 +1358,12 @@ export class CoreDomUtilsProvider {
|
|||
*
|
||||
* @param element The element to scroll to.
|
||||
* @param selector Selector to find the element to scroll to inside the defined element.
|
||||
* @param duration Duration of the scroll animation in milliseconds.
|
||||
* @param scrollOptions Scroll Options.
|
||||
* @return Wether the scroll suceeded.
|
||||
*/
|
||||
async scrollViewToElement(element: HTMLElement, selector?: string, duration = 0): Promise<boolean> {
|
||||
await CoreDomUtils.waitToBeInDOM(element);
|
||||
|
||||
async scrollViewToElement(element: HTMLElement, selector?: string, scrollOptions: CoreScrollOptions = {}): Promise<boolean> {
|
||||
if (selector) {
|
||||
const foundElement = element.querySelector<HTMLElement>(selector);
|
||||
const foundElement = await CoreDomUtils.waitToBeInsideElement(element, selector);
|
||||
if (!foundElement) {
|
||||
// Element not found.
|
||||
return false;
|
||||
|
@ -1336,16 +1372,28 @@ export class CoreDomUtilsProvider {
|
|||
element = foundElement;
|
||||
}
|
||||
|
||||
await CoreDomUtils.waitToBeVisible(element);
|
||||
|
||||
const content = element.closest<HTMLIonContentElement>('ion-content') ?? undefined;
|
||||
if (!content) {
|
||||
|
||||
// Content to scroll, not found.
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
const position = CoreDomUtils.getRelativeElementPosition(element, content);
|
||||
const scrollElement = await content.getScrollElement();
|
||||
|
||||
await content.scrollToPoint(position.x, position.y, duration);
|
||||
scrollOptions.duration = scrollOptions.duration ?? 200;
|
||||
scrollOptions.addXAxis = scrollOptions.addXAxis ?? 0;
|
||||
scrollOptions.addYAxis = scrollOptions.addYAxis ?? 0;
|
||||
|
||||
await content.scrollToPoint(
|
||||
position.x + scrollElement.scrollLeft + scrollOptions.addXAxis,
|
||||
position.y + scrollElement.scrollTop + scrollOptions.addYAxis,
|
||||
scrollOptions.duration,
|
||||
);
|
||||
|
||||
return true;
|
||||
} catch {
|
||||
|
@ -1373,8 +1421,8 @@ export class CoreDomUtilsProvider {
|
|||
* @return True if the element is found, false otherwise.
|
||||
* @deprecated since app 4.0 Use scrollViewToElement instead.
|
||||
*/
|
||||
scrollToElement(content: IonContent, element: HTMLElement, scrollParentClass?: string, duration = 0): boolean {
|
||||
CoreDomUtils.scrollViewToElement(element, undefined, duration);
|
||||
scrollToElement(content: IonContent, element: HTMLElement, scrollParentClass?: string, duration?: number): boolean {
|
||||
CoreDomUtils.scrollViewToElement(element, undefined, { duration });
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1395,13 +1443,13 @@ export class CoreDomUtilsProvider {
|
|||
content: unknown | null,
|
||||
selector: string,
|
||||
scrollParentClass?: string,
|
||||
duration = 0,
|
||||
duration?: number,
|
||||
): boolean {
|
||||
if (!container || !content) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CoreDomUtils.scrollViewToElement(container, selector, duration);
|
||||
CoreDomUtils.scrollViewToElement(container, selector, { duration });
|
||||
|
||||
return true;
|
||||
|
||||
|
@ -2435,3 +2483,12 @@ export type CoreCoordinates = {
|
|||
x: number; // X axis coordinates.
|
||||
y: number; // Y axis coordinates.
|
||||
};
|
||||
|
||||
/**
|
||||
* Scroll options.
|
||||
*/
|
||||
export type CoreScrollOptions = {
|
||||
duration?: number;
|
||||
addYAxis?: number;
|
||||
addXAxis?: number;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue