iframe内部angular2组件,属性'contentWindow'在类型'HTMLElem

iframe inside angular2 component, Property 'contentWindow' does not exist on type 'HTMLElement'

本文关键字:contentWindow 类型 HTMLElem 内部 angular2 属性 iframe 组件      更新时间:2023-09-26

我在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启动),我有编译错误,消息是:

类型"HTMLElement"上不存在属性"contentWindow"

我还尝试了将成本构造函数的代码放入ngOnInit()、ngAfterContentInit(。

当构造函数执行时,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();
  }
}

使用这个:

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

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

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

如果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演示

或者这个Stacklitz演示

这将使原生HTML元素保持不变,从而与Angular Universal保持兼容。

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

DOM在Constructor中还没有准备好,但您可以在ngOnInit事件中发现它已经准备好了,不过可以使用{static:true}属性,类似于以下内容:

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

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

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

或者使用现在著名的Typescript作品:

iframe['contentWindow']