iframe with scrollbar =不会触发滚动事件(angular2)

时间:2017-01-02 14:25:28

标签: angular events iframe scroll

我有一个angular2应用程序,它有一个标题,内容在iframe中。我使用:html {overflow-y:hidden;}禁用了css文件中的窗口滚动条,我的目标是使用动画来实现粘性标题。

我尝试了一些选项,但在我看来,他们都没有触发/监听iframe的滚动事件(窗口或doscument滚动事件正在激活而没有问题,但我不需要它):

选项1(当我尝试(加载)而不是(滚动)时,它可以工作):

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

选项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..');
    })

  }

你知道为什么滚动事件没有激发吗?

1 个答案:

答案 0 :(得分:2)

您可能已经找到了解决方案,但我最近遇到了这个问题并且没有回答就找到了这个问题。 关键似乎是您注册事件通知的时间。在iframe的onload事件被触发后,您必须注册滚动事件。在我的代码中,我在模板代码中注册了iframe的onload事件。

<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>

在类本身中我有iframe ElementRef成员(以及我想要响应scroll事件更新的布尔成员, 更多关于此答案的后续内容..)。

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

  scroll$: any = null;

}

然后在RouteFrame类的onFrameLoad()方法中注册滚动事件。

onFrameLoad() {

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

然后在onScroll()方法中,执行您需要的任何逻辑。在我的情况下,当用户滚动到iframe的底部时,我正在观看。 然而,我发现滚动事件发生在外面&#39; Angular,因此Angular对该变量的值的变化重新评估了表单,因此即使它接受按钮也从未启用 有[禁用] =&#34;!scrollBottom&#34;作为其声明的一部分。因此,为什么对scrollBottom变量的更新包含在this.zone.run()。

onScroll() {

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

this.zone就像在RouteFrame类的cstr中一样注入其他Angular提供程序。

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

为了完整性,在组件完成时取消订阅滚动事件侦听器。

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

Angular版本4.3.0