【问题标题】:iframe inside angular2 component, Property 'contentWindow' does not exist on type 'HTMLElement'angular2 组件内的 iframe,“HTMLElement”类型上不存在属性“contentWindow”
【发布时间】:2016-11-22 07:08:04
【问题描述】:

我在 angular2 组件中有一个 iframe,我正在尝试通过访问 contentWindow 来更改 iframe 的内容。
iframe 应该包含一个简单的按钮。

我的代码:

    import { Component } from '@angular/core';
    @Component({
      moduleId: module.id,
      selector: 'component-iframe',
      template: '<iframe id="iframe"></iframe>'
    })
    export class ComponentIframe  {
      constructor() {
        let iframe = document.getElementById('iframe'); 
        let content = '<button id="button" class="button" >My button </button>';
        let doc =  iframe.contentDocument || iframe.contentWindow;
        doc.open();
        doc.write(content);
      doc.close();
    }
   }

如果我注释构造函数的代码并启动应用程序,它会正确编译并运行。然后我取消注释,一切运行完美(按钮存在于 iframe 中)。

如果我取消代码然后启动应用程序 (npm start) 我有编译错误消息:

“HTMLElement”类型上不存在属性“contentWindow”

.

我还尝试了将构造函数的代码放入 ngOnInit()、ngAfterContentInit()、ngAfterViewInit() 的替代方法,但错误仍然存​​在。

【问题讨论】:

    标签: javascript iframe angular


    【解决方案1】:

    执行构造函数时模板在DOM中还不存在

    改为使用

    import { Component, ViewChild, ElementRef } from '@angular/core';
    @Component({
      moduleId: module.id,
      selector: 'component-iframe',
      template: '<iframe #iframe></iframe>'
    })
    export class ComponentIframe  {
      @ViewChild('iframe') iframe: ElementRef;
    
      ngAfterViewInit() {
        let content = '<button id="button" class="button" >My button </button>';
        let doc =  this.iframe.nativeElement.contentDocument || this.iframe.nativeElement.contentWindow;
        doc.open();
        doc.write(content);
        doc.close();
      }
    }
    

    【讨论】:

      【解决方案2】:

      使用这个:

      let iframe = document.getElementById('iframe') as HTMLIFrameElement
      

      【讨论】:

        【解决方案3】:

        我通过以下方式解决了这个问题:

        const element: HTMLIFrameElement = document.getElementById('iframe') as HTMLIFrameElement;
        const iframe = element.contentWindow;
        if (iframe !== null) {
          ...
        }
        

        【讨论】:

          【解决方案4】:

          如果 IFRAME 的内容是由 同源 创建的,那么我建议使用 IFRAME 属性 srcDoc 来设置和更改IFRAME 中的内容。

          @Component({
            selector: 'my-app',
            template: `
              <p><label for="text">Write content here...</label></p>
              <textarea 
                  #text
                  rows="10" 
                  cols="47" 
                  placeholder="Write some HTML content here..." 
                  [(ngModel)]="srcDocContent"></textarea>
          
              <p>Preview HTML content in IFRAME</p>
              <iframe 
                  sandbox="allow-same-origin" 
                  [attr.srcDoc]="srcDocContent"></iframe>
            `
          })
          export class App {
          
            srcDocContent:string
          
            constructor() {
              this.srcDocContent='Some <strong>HTML</strong> content here...'
            }
          }
          

          看到这个PLUNKER DEMO

          或者这个Stackblitz DEMO

          这将使原生 HTML 元素保持与 Angular Universal 兼容。

          【讨论】:

            【解决方案5】:

            因为 Günter Zöchbauer 已经正确回答了这个问题。我想稍微修改一下。

            DOM 尚未在 Constructor 中准备好,但您可以通过使用 { static: true } em> 属性是这样的:

            import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
            @Component({
              moduleId: module.id,
              selector: 'component-iframe',
              template: '<iframe #iframe></iframe>'
            })
            export class ComponentIframe implements OnInit {
              @ViewChild('iframe', { static: true }) iframe: ElementRef;
            
              ngOnInit() {
                let content = '<button id="button" class="button" >My button </button>';
                let doc =  this.iframe.nativeElement.contentDocument || this.iframe.nativeElement.contentWindow;
                doc.open();
                doc.write(content);
                doc.close();
              }
            }
            

            【讨论】:

              【解决方案6】:

              我通过以下方式解决了这个问题:

               var ID = document.getElementById("Iframe");
               var Iframe = eval("(ID.contentWindow || ID.contentDocument)");
               Iframe.CallIframeFunction();
              

              【讨论】:

                【解决方案7】:

                或者使用现在著名的 Typescript 解决方法:

                iframe['contentWindow']
                

                【讨论】:

                  猜你喜欢
                  • 2022-01-13
                  • 2021-12-15
                  • 2019-09-16
                  • 2017-08-08
                  • 2018-10-19
                  • 2019-11-21
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多