代码之家  ›  专栏  ›  技术社区  ›  amitairos

4滚动时隐藏工具栏

  •  3
  • amitairos  · 技术社区  · 7 年前

    我正在尝试实现一个在滚动时隐藏工具栏的指令。 我试着使用这个教程: https://medium.com/@gregor.srdic/ionic3-hidding-header-on-footer-on-content-scroll-15ab95b05dc5

    在以下代码中,我得到错误:

    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;
            });
        }
    }
    

    错误:

    ev.domWrite is not a function
    

    我查过了,然后 ev 在离子4中是 CustomEvent ,不是 ScrollEvent .

    4 回复  |  直到 7 年前
        1
  •  8
  •   Sankha Karunasekara    7 年前

    上述解决方案不再有效。离子4βAPI在最近几个月发生了很大的变化。

    你必须导入 IonContent Content .

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

    将指令导入到要使用它的位置,而不是 app.module.ts

    //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 };
    ...
    
    }
    

    指令的反向版本

    //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;
    }
    

    <ion-header [scrollHide]="headerScrollConfig" [scrollContent]="pageContent">
      ...
    </ion-header>
    
    <ion-content #pageContent fullscreen>
      ...
    </ion-content>
    
    <ion-footer [scrollHide]="footerScrollConfig" [scrollContent]="pageContent">
    ...
    </ion-footer>
    

    希望有帮助。

        2
  •  6
  •   Yuyinitos    7 年前

    离子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;
    }
        3
  •  5
  •   sebaferreras    7 年前

    事件在Ionic 4中可能已更改,但您仍然可以导入 DomController @ionic/angular

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

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

    然后使用 write() 方法如下:

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

    这个 window.requestAnimationFrame()

    有关更多信息,请访问:

    1. DomController source code
    2. requestAnimationFrame MDN
        4
  •  0
  •   Mahesh Siva S T    7 年前

    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;
    }
    
    推荐文章