简体   繁体   English

angular2 组件内的 iframe,“HTMLElement”类型上不存在属性“contentWindow”

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

I have an iframe inside a angular2 component, and I am trying to change the content of the iframe by accessing the contentWindow.我在 angular2 组件中有一个 iframe,我试图通过访问 contentWindow 来更改 iframe 的内容。
The iframe should contain a simple button. iframe 应该包含一个简单的按钮。

My code:我的代码:

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

If I comment the constructor's code and start the app, it compiles and runs correctly.如果我注释构造函数的代码并启动应用程序,它会正确编译和运行。 Then I uncomment and all runs perfectly (the button is present in the iframe).然后我取消注释并且所有运行都完美(该按钮存在于 iframe 中)。

If I decomment the code then start the app (npm start) I have compilation bugs with the message:如果我对代码进行注释,然后启动应用程序(npm start),则会出现带有消息的编译错误:

Property 'contentWindow' does not exist on type 'HTMLElement' “HTMLElement”类型上不存在属性“contentWindow”

. .

I also tried the alternative of putting the costructor's code into ngOnInit(), ngAfterContentInit(), ngAfterViewInit() but the error persists.我还尝试了将 costructor 的代码放入 ngOnInit()、ngAfterContentInit()、ngAfterViewInit() 的替代方法,但错误仍然存​​在。

The template doesn't exist in the DOM yet when the constructor is executed执行构造函数时模板还不存在于 DOM 中

Use instead改用

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

I solved the problem in the following way:我通过以下方式解决了这个问题:

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

If the content of the IFRAME is created by the same origin then I would suggest to use the IFRAME attribute srcDoc to set and change content in IFRAME.如果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...'
  }
}

See this PLUNKER DEMO看到这个PLUNKER 演示

or this Stackblitz DEMO或者这个Stackblitz DEMO

This will let the native HTML elements untouched to remain compatible with Angular Universal.这将使原生 HTML 元素保持不变,以保持与 Angular Universal 的兼容。

As Günter Zöchbauer has already answered it correctly.正如 Günter Zöchbauer 已经正确回答了。 I would like to modify it a bit.我想稍微修改一下。

The DOM is not ready in Constructor yet but you can find it ready in ngOnInit event though by using { static: true } property something like this: DOM 尚未在构造函数中准备好,但您可以通过使用{ static: true }属性在ngOnInit事件中找到它,如下所示:

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

I solved the problem in the following way:我通过以下方式解决了这个问题:

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

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

iframe['contentWindow']

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM