web-dev-qa-db-fra.com

Ionic 4 Masquer la barre d'outils lors du défilement

J'essaie d'implémenter une directive pour masquer la barre d'outils lors du défilement. J'ai essayé d'utiliser ce tutoriel: https://medium.com/@gregor.srdic/ionic3-hidding-header-on-footer-on-content-scroll-15ab95b05dc5

Cela a fonctionné avec Ionic 3, mais ne fonctionne pas avec Ionic 4.

Sur le code suivant, j'obtiens l'erreur:

private adjustElementOnScroll(ev) {
    if (ev) {
        console.log(ev);
        ev.domWrite(() => {
            let scrollTop: number = ev.scrollTop > 0 ? ev.scrollTop : 0;
            let scrolldiff: number = scrollTop - this.lastScrollPosition;
            this.lastScrollPosition = scrollTop;
            let newValue = this.lastValue + scrolldiff;
            newValue = Math.max(0, Math.min(newValue, this.config.maxValue));
            this.renderer.setStyle(this.element.nativeElement, this.config.cssProperty, `-${newValue}px`);
            this.lastValue = newValue;
        });
    }
}

Erreur:

ev.domWrite is not a function

J'ai vérifié et ev dans Ionic 4 est un CustomEvent, pas un ScrollEvent.

Aucune suggestion?

5
amitairos

Les solutions ci-dessus ne fonctionnent plus. Ionic 4 API bêta ont beaucoup changé ces derniers mois.

vous devez importer IonContent au lieu de Content.

//scroll-hide.directive.ts
import { IonContent, DomController } from '@ionic/angular';
import { Directive, ElementRef, Input, Renderer2, SimpleChanges } from '@angular/core';

importez la directive où vous voulez l'utiliser, au lieu de app.module.ts

par exemple dans le module correspondant,

//ex: home.module.ts
import { ScrollHideDirective } from '../../directives/scroll-hide.directive';

@NgModule({
    ...
  declarations: [...,ScrollHideDirective],
    ...
})


then in the ts file,


//ex: home.page.ts
import { ScrollHideConfig } from '../../directives/scroll-hide.directive';


export class HomePage implements OnInit {

...
    footerScrollConfig: ScrollHideConfig = { cssProperty: 'margin-bottom', maxValue: undefined };
    headerScrollConfig: ScrollHideConfig = { cssProperty: 'margin-top', maxValue: 54 };
...

}

version inversée de la directive

//ex: scroll-hide.directive.ts    

import { IonContent, DomController } from '@ionic/angular';
import { Directive, ElementRef, Input, Renderer2, SimpleChanges } from '@angular/core';

    @Directive({
      selector: '[scrollHide]'
      })
export class ScrollHideDirective {

  @Input('scrollHide') config: ScrollHideConfig;
  @Input('scrollContent') scrollContent: IonContent;

  contentHeight: number;
  scrollHeight: number;
  lastScrollPosition: number;
  lastValue: number = 0;

  constructor(private element: ElementRef, private renderer: Renderer2, private  domCtrl: DomController) {
  }

  ngOnChanges(changes: SimpleChanges) {
    if(this.scrollContent && this.config) {
      this.scrollContent.scrollEvents = true;

      let scrollStartFunc = async (ev) => {
        const el = await this.scrollContent.getScrollElement();
        this.contentHeight = el.offsetHeight;
        this.scrollHeight = el.scrollHeight;
        if (this.config.maxValue === undefined) {
          this.config.maxValue = this.element.nativeElement.offsetHeight;
        }
        this.lastScrollPosition = el.scrollTop;
      };

      if(this.scrollContent && this.scrollContent instanceof IonContent) {
        this.scrollContent.ionScrollStart.subscribe(scrollStartFunc);
        this.scrollContent.ionScroll.subscribe(async (ev) => this.adjustElementOnScroll(ev));
        this.scrollContent.ionScrollEnd.subscribe(async (ev) => this.adjustElementOnScroll(ev));

      } else if(this.scrollContent instanceof HTMLElement) {
        (this.scrollContent as HTMLElement).addEventListener('ionScrollStart', scrollStartFunc);
        (this.scrollContent as HTMLElement).addEventListener('ionScroll',async (ev) => this.adjustElementOnScroll(ev));
        (this.scrollContent as HTMLElement).addEventListener('ionScrollEnd',async (ev) => this.adjustElementOnScroll(ev));
      }
    }
  }

  private adjustElementOnScroll(ev) {
    if (ev) {
      this.domCtrl.write(async () => {
        const el = await this.scrollContent.getScrollElement();
        let scrollTop: number = el.scrollTop > 0 ? el.scrollTop : 0;
        let scrolldiff: number = scrollTop - this.lastScrollPosition;
        this.lastScrollPosition = scrollTop;
        let newValue = this.lastValue + scrolldiff;
        newValue = Math.max(0, Math.min(newValue, this.config.maxValue));
        this.renderer.setStyle(this.element.nativeElement, this.config.cssProperty, `-${newValue}px`);
        this.lastValue = newValue;
      });
    }
  }
}

export interface ScrollHideConfig {
  cssProperty: string;
  maxValue: number;
}

le html ex: page.html (pas de changement)

<ion-header [scrollHide]="headerScrollConfig" [scrollContent]="pageContent">
  ...
</ion-header>

<ion-content #pageContent fullscreen>
  ...
</ion-content>

<ion-footer [scrollHide]="footerScrollConfig" [scrollContent]="pageContent">
...
</ion-footer>

j'espère que ça aide.

1
Lakshan S

Directive modifiée pour Ionic 4.

import { Content, DomController } from '@ionic/angular';
import { Directive, ElementRef, Input, Renderer2, SimpleChanges } from '@angular/core';

@Directive({
    selector: '[scrollHide]'
})
export class ScrollHideDirective {

    @Input('scrollHide') config: ScrollHideConfig;
    @Input('scrollContent') scrollContent: Content;

    contentHeight: number;
    scrollHeight: number;
    lastScrollPosition: number;
    lastValue: number = 0;

    constructor(private element: ElementRef, private renderer: Renderer2, private domCtrl: DomController) {
    }

    ngOnChanges(changes: SimpleChanges) {
        if (this.scrollContent && this.config) {
            this.scrollContent.ionScrollStart.subscribe(async (ev) => {
                const el = await this.scrollContent.getScrollElement();
                this.contentHeight = el.offsetHeight;
                this.scrollHeight = el.scrollHeight;    
                if (this.config.maxValue === undefined) {
                    this.config.maxValue = this.element.nativeElement.offsetHeight;
                }
                this.lastScrollPosition = el.scrollTop;
            });
            this.scrollContent.ionScroll.subscribe((ev) => this.adjustElementOnScroll(ev));
            this.scrollContent.ionScrollEnd.subscribe((ev) => this.adjustElementOnScroll(ev));
        }
    }

    private adjustElementOnScroll(ev) {
        if (ev) {
            this.domCtrl.write(async () => {
                const el = await this.scrollContent.getScrollElement();
                let scrollTop: number = el.scrollTop > 0 ? el.scrollTop : 0;
                let scrolldiff: number = scrollTop - this.lastScrollPosition;
                this.lastScrollPosition = scrollTop;
                let newValue = this.lastValue + scrolldiff;
                newValue = Math.max(0, Math.min(newValue, this.config.maxValue));
                this.renderer.setStyle(this.element.nativeElement, this.config.cssProperty, `-${newValue}px`);
                this.lastValue = newValue;
            });
        }
    }
}
export interface ScrollHideConfig {
    cssProperty: string;
    maxValue: number;
}
2
Yuyinitos

L'événement peut avoir changé dans Ionic 4, mais vous pouvez toujours importer le DomController de @ionic/angular

import {..., DomController } from "@ionic/angular";

et l'injecter dans le constructeur

constructor(
    // ...
    private domCtrl: DomController
) { }

Et puis utilisez la méthode write() comme ceci:

private adjustElementOnScroll(ev) {
    if (ev) {
        this.domCtrl.write(() => {
            // ...
        });
    }
}

Le DomController est juste un moyen pour Ionic de créer une file d'attente pour les rappels qui écriraient ou liraient le DOM afin d'utiliser la méthode window.requestAnimationFrame() derrière le scènes.

Pour plus d'informations, s'il vous plaît visitez:

  1. DomController code source
  2. requestAnimationFrame MDN
2
sebaferreras

Le code ci-dessous a fonctionné pour moi, avec des corrections mineures du code ci-dessus

import { Content, DomController } from '@ionic/angular';
import { Directive, ElementRef, Input, Renderer2, SimpleChanges } from '@angular/core';

@Directive({
  selector: '[scrollHide]'
  })
export class ScrollHideDirective {

  @Input('scrollHide') config: ScrollHideConfig;
  @Input('scrollContent') scrollContent: Content;

  contentHeight: number;
  scrollHeight: number;
  lastScrollPosition: number;
  lastValue: number = 0;

  constructor(private element: ElementRef, private renderer: Renderer2, private domCtrl: DomController) {
  }

  ngOnChanges(changes: SimpleChanges) {
    if(this.scrollContent && this.config) {
      this.scrollContent.scrollEvents = true;

      let scrollStartFunc = async (ev) => {
        const el = await this.scrollContent.getScrollElement();
        this.contentHeight = el.offsetHeight;
        this.scrollHeight = el.scrollHeight;
        if (this.config.maxValue === undefined) {
          this.config.maxValue = this.element.nativeElement.offsetHeight;
        }
        this.lastScrollPosition = el.scrollTop;
      };

      if(this.scrollContent && this.scrollContent instanceof Content) {
        this.scrollContent.ionScrollStart.subscribe(scrollStartFunc);
        this.scrollContent.ionScroll.subscribe(async (ev) => this.adjustElementOnScroll(ev));
        this.scrollContent.ionScrollEnd.subscribe(async (ev) => this.adjustElementOnScroll(ev));

      } else if(this.scrollContent instanceof HTMLElement) {
        (this.scrollContent as HTMLElement).addEventListener('ionScrollStart', scrollStartFunc);
        (this.scrollContent as HTMLElement).addEventListener('ionScroll',async (ev) => this.adjustElementOnScroll(ev));
        (this.scrollContent as HTMLElement).addEventListener('ionScrollEnd',async (ev) => this.adjustElementOnScroll(ev));
      }
    }
  }

  private adjustElementOnScroll(ev) {
    if (ev) {
      this.domCtrl.write(async () => {
        const el = await this.scrollContent.getScrollElement();
        let scrollTop: number = el.scrollTop > 0 ? el.scrollTop : 0;
        let scrolldiff: number = scrollTop - this.lastScrollPosition;
        this.lastScrollPosition = scrollTop;
        let newValue = this.lastValue + scrolldiff;
        newValue = Math.max(0, Math.min(newValue, this.config.maxValue));
        this.renderer.setStyle(this.element.nativeElement, this.config.cssProperty, `-${newValue}px`);
        this.lastValue = newValue;
      });
    }
  }
}
export interface ScrollHideConfig {
  cssProperty: string;
  maxValue: number;
}
0
Mahesh Siva S T