【问题标题】:iframe with scrollbar = does not fire scroll event (angular2)带有滚动条的 iframe = 不会触发滚动事件 (angular2)
【发布时间】:2017-01-02 14:25:27
【问题描述】:

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

我尝试了一些选项,但我认为它们都没有触发/监听 iframe 的滚动事件(窗口或文档滚动事件触发没有问题,但我不需要它):

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

  }

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

【问题讨论】:

    标签: angular events iframe scroll


    【解决方案1】:

    您可能已经找到了解决方案,但我最近正好遇到了这个问题,发现这个问题没有答案。 关键似乎是您注册事件通知的时间。在 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 成员(以及我想要更新以响应滚动事件的布尔成员, 稍后将在此答案中详细介绍..)。

    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 底部时,我正在观看。 然而,我发现滚动事件发生在 Angular 的“外部”,因此 Angular 会根据该变量的值变化重新评估表单,因此即使接受按钮也从未启用 将 [disabled]="!scrollBottom" 作为其声明的一部分。因此,为什么对 scrollBottom 变量的更新包含在 this.zone.run() 中。

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

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

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

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

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

    Angular 4.3.0 版

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-10
      • 1970-01-01
      • 2023-01-06
      • 2015-01-29
      • 2011-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多