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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38457662/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 21:31:09  来源:igfitidea点击:

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

javascriptiframeangular

提问by gabriela

I have an iframe inside a angular2 component, and I am trying to change the content of the iframe by accessing the contentWindow.
The iframe should contain a simple button.

我在 angular2 组件中有一个 iframe,我试图通过访问 contentWindow 来更改 iframe 的内容。
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() 的替代方法,但错误仍然存​​在。

回答by Günter Z?chbauer

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

回答by Eldos Narbay

use this:

用这个:

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

回答by Pablo

I solved the problem in the following way:

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

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

回答by Yoraco Gonzales

If the content of the IFRAMEis created by the same originthen I would suggest to use the IFRAME attribute srcDocto 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 的兼容。

回答by Jameer Khan

As Günter Z?chbauer has already answered it correctly. I would like to modify it a bit.

正如 Günter Z?chbauer 已经正确回答了。我想稍微修改一下。

The DOM is not ready in Constructor yet but you can find it ready in ngOnInitevent 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();
  }
}

回答by Deepak Sharma

I solved the problem in the following way:

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

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

回答by SoEzPz

Or use the now famous Typescript work around:

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

iframe['contentWindow']