2017-01-02 2 views
0

Ich habe eine angular2-Anwendung, die einen Header hat und der Inhalt ist in einem iframe. Ich deaktivierte die Fensterlaufleiste in der CSS-Datei mit: html {overflow-y: hidden;} und mein Ziel ist es, einen sticky header mit einer Animation zu erreichen.iframe mit scrollbar = Scroll-Ereignis wird nicht ausgelöst (angular2)

habe ich versucht, einige Optionen, aber von ihnen meiner Meinung nach keine sind fireing/zum Scroll-Ereignis des iframe hören (Fenster oder doscument Scroll-Ereignis ohne Probleme fireing, aber ich brauche es nicht):

Option 1 (wenn ich versuche (Last) anstelle von (scroll), es funktioniert):

<iframe src=".." scrolling="yes" (scroll)="iframeScrollHandler(event)">..</iframe> 

Option 2:

@ViewChild('iframe') iframe: ElementRef; 
constructor(@Inject(DOCUMENT) private document: Document, private window: Window, private renderer:Renderer) { 
    } 

    ngAfterViewInit(){ 
    this.renderer.listen(this.iframe.nativeElement, 'scroll', (event) => { 
     console.log('scroll scroll..'); 
    }) 

    } 

wissen Sie, warum das Scroll-Ereignis ist nicht fireing?

Antwort

1

Sie haben vielleicht schon eine Lösung gefunden, aber ich bin kürzlich auf dieses Problem gestoßen und habe diese Frage ohne Antwort gefunden. Der Schlüssel scheint der Zeitpunkt zu sein, zu dem Sie sich für Ereignisbenachrichtigungen registrieren. Sie müssen sich für das Scroll-Ereignis registrieren, nachdem das Onload-Ereignis des IFrames ausgelöst wurde. In meinem Code habe ich mich für das Onload-Ereignis des Iframes in meinem Vorlagencode registriert.

<form ngNoForm action="/logout" method="post" role="form"> 
    <div class="container-fluid main"> 
     <iframe #tframe [src]="src" class="frame" (load)="onFrameLoad()"> </iframe> 
     <div class="clearfix"> 
      <div class="pull-right"> 
       <button type="submit" class="btn btn-dialog-secondary">{{'common.decline' | i18n}}</button> 
       <button type="button" [disabled]="!scrollBottom" id="defaultFocus" class="btn btn-primary" (click)="accept()">{{'common.accept' | i18n}}</button> 
      </div> 
     </div> 
    </div> 
</form> 

In der Klasse selbst hatte ich das iframe ElementRef Mitglied (aswell als boolean Element, das ich als Antwort auf das Scroll-Ereignis aktualisieren wollte, dazu später mehr in dieser Antwort ..).

export class RouteFrame implements AfterViewInit { 
    scrollBottom: boolean = false; 
    @ViewChild('tframe') frame : ElementRef; 

    scroll$: any = null; 

}

Dann im onFrameLoad() Methode des RouteFrame Klassenregisters für das Scroll-Ereignis.

onFrameLoad() { 

    this.scroll$ = Observable.fromEvent(this.frame.nativeElement.contentWindow, 'scroll') 
     .debounceTime(200) 
     .subscribe((evt: any) => { 
      this.onScroll(); 
     }); 
} 

Dann in der onScroll() - Methode, was auch immer Logik Sie brauchen. In meinem Fall habe ich beobachtet, als der Benutzer zum unteren Rand des iFrame scrollte. Was ich jedoch fand, war, dass das Scroll-Ereignis 'außerhalb' von Angular stattfand, also wurde das Formular von Angular auf die Wertänderung dieser Variable überprüft, so dass der Akzeptieren-Button nie aktiviert wurde, obwohl er den [ ] hatte. deaktiviert] = "! scrollBottom" als Teil der Deklaration. Daher wird das Update für die Variable scrollBottom in this.zone.run() eingeschlossen.

onScroll() { 

    if (this.frame.nativeElement.contentWindow.scrollY > this.frame.nativeElement.contentWindow.innerHeight) { 
     this.zone.run(() => { 
      this.scrollBottom = true; 
     }); 
    } 
} 

this.zone wird gerade wie andere Angular-Provider in den cstr der RouteFrame-Klasse injiziert.

constructor(@Inject(NgZone) private zone: NgZone, ....) 

Der Vollständigkeit halber den Scroll-Event-Listener abbestellen, wenn die Komponente fertig ist.

NgOnDestroy() { 
    this.scroll$.unsubscribe(); 
} 

Angular Version 4.3.0