mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-18 11:17:19 +08:00
fix(refresher): refresher is visible with multiple custom scroll targets (#25750)
Resolves #25495
This commit is contained in:
1
core/src/components.d.ts
vendored
1
core/src/components.d.ts
vendored
@ -671,6 +671,7 @@ export namespace Components {
|
|||||||
* If `true`, the content will scroll behind the headers and footers. This effect can easily be seen by setting the toolbar to transparent.
|
* If `true`, the content will scroll behind the headers and footers. This effect can easily be seen by setting the toolbar to transparent.
|
||||||
*/
|
*/
|
||||||
"fullscreen": boolean;
|
"fullscreen": boolean;
|
||||||
|
"getBackgroundElement": () => Promise<HTMLElement>;
|
||||||
/**
|
/**
|
||||||
* Get the element where the actual scrolling takes place. This element can be used to subscribe to `scroll` events or manually modify `scrollTop`. However, it's recommended to use the API provided by `ion-content`: i.e. Using `ionScroll`, `ionScrollStart`, `ionScrollEnd` for scrolling events and `scrollToPoint()` to scroll the content into a certain point.
|
* Get the element where the actual scrolling takes place. This element can be used to subscribe to `scroll` events or manually modify `scrollTop`. However, it's recommended to use the API provided by `ion-content`: i.e. Using `ionScroll`, `ionScrollStart`, `ionScrollEnd` for scrolling events and `scrollToPoint()` to scroll the content into a certain point.
|
||||||
*/
|
*/
|
||||||
|
@ -28,6 +28,7 @@ export class Content implements ComponentInterface {
|
|||||||
private cTop = -1;
|
private cTop = -1;
|
||||||
private cBottom = -1;
|
private cBottom = -1;
|
||||||
private scrollEl?: HTMLElement;
|
private scrollEl?: HTMLElement;
|
||||||
|
private backgroundContentEl?: HTMLElement;
|
||||||
private isMainContent = true;
|
private isMainContent = true;
|
||||||
|
|
||||||
// Detail is used in a hot loop in the scroll event, by allocating it here
|
// Detail is used in a hot loop in the scroll event, by allocating it here
|
||||||
@ -188,6 +189,18 @@ export class Content implements ComponentInterface {
|
|||||||
return Promise.resolve(this.scrollEl!);
|
return Promise.resolve(this.scrollEl!);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the background content element.
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
@Method()
|
||||||
|
async getBackgroundElement(): Promise<HTMLElement> {
|
||||||
|
if (!this.backgroundContentEl) {
|
||||||
|
await new Promise((resolve) => componentOnReady(this.el, resolve));
|
||||||
|
}
|
||||||
|
return Promise.resolve(this.backgroundContentEl!);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scroll to the top of the component.
|
* Scroll to the top of the component.
|
||||||
*
|
*
|
||||||
@ -332,7 +345,7 @@ export class Content implements ComponentInterface {
|
|||||||
'--offset-bottom': `${this.cBottom}px`,
|
'--offset-bottom': `${this.cBottom}px`,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div id="background-content" part="background"></div>
|
<div ref={(el) => (this.backgroundContentEl = el)} id="background-content" part="background"></div>
|
||||||
<TagType
|
<TagType
|
||||||
class={{
|
class={{
|
||||||
'inner-scroll': true,
|
'inner-scroll': true,
|
||||||
|
@ -443,15 +443,17 @@ export class Refresher implements ComponentInterface {
|
|||||||
console.error('Make sure you use: <ion-refresher slot="fixed">');
|
console.error('Make sure you use: <ion-refresher slot="fixed">');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const contentEl = this.el.closest(ION_CONTENT_ELEMENT_SELECTOR);
|
const contentEl = this.el.closest(ION_CONTENT_ELEMENT_SELECTOR);
|
||||||
if (!contentEl) {
|
if (!contentEl) {
|
||||||
printIonContentErrorMsg(this.el);
|
printIonContentErrorMsg(this.el);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Waits for the content to be ready before querying the scroll
|
||||||
|
* or the background content element.
|
||||||
|
*/
|
||||||
|
await contentEl.componentOnReady();
|
||||||
const customScrollTarget = contentEl.querySelector(ION_CONTENT_CLASS_SELECTOR);
|
const customScrollTarget = contentEl.querySelector(ION_CONTENT_CLASS_SELECTOR);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query the custom scroll target (if available), first. In refresher implementations,
|
* Query the custom scroll target (if available), first. In refresher implementations,
|
||||||
* the ion-refresher element will always be a direct child of ion-content (slot="fixed"). By
|
* the ion-refresher element will always be a direct child of ion-content (slot="fixed"). By
|
||||||
@ -459,18 +461,10 @@ export class Refresher implements ComponentInterface {
|
|||||||
* the correct scroll element will be returned by the implementation.
|
* the correct scroll element will be returned by the implementation.
|
||||||
*/
|
*/
|
||||||
this.scrollEl = await getScrollElement(customScrollTarget ?? contentEl);
|
this.scrollEl = await getScrollElement(customScrollTarget ?? contentEl);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query the host `ion-content` directly (if it is available), to use its
|
* Query the background content element from the host ion-content element directly.
|
||||||
* inner #background-content has the target. Otherwise fallback to the
|
|
||||||
* custom scroll target host.
|
|
||||||
*
|
|
||||||
* This makes it so that implementers do not need to re-create the background content
|
|
||||||
* element and styles.
|
|
||||||
*/
|
*/
|
||||||
this.backgroundContentEl = getElementRoot(contentEl ?? customScrollTarget).querySelector(
|
this.backgroundContentEl = await contentEl.getBackgroundElement();
|
||||||
'#background-content'
|
|
||||||
) as HTMLElement;
|
|
||||||
|
|
||||||
if (await shouldUseNativeRefresher(this.el, getIonMode(this))) {
|
if (await shouldUseNativeRefresher(this.el, getIonMode(this))) {
|
||||||
this.setupNativeRefresher(contentEl);
|
this.setupNativeRefresher(contentEl);
|
||||||
|
Reference in New Issue
Block a user