web-dev-qa-db-ja.com

angular2コンポーネント内のiframe、プロパティ「contentWindow」はタイプ「HTMLElement」に存在しません

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)、メッセージにコンパイルのバグがあります。

プロパティ 'contentWindow'はタイプ 'HTMLElement'に存在しません

また、コストラクタのコードをngOnInit()、ngAfterContentInit()、ngAfterViewInit()に入れるという代替手段も試しましたが、エラーは続きます。

13
gabriela

コンストラクターが実行されるとき、テンプレートはまだ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();
  }
}
20

これを使って:

let iframe = document.getElementById('iframe') as HTMLIFrameElement
11
Eldos Narbay

次の方法で問題を解決しました。

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

[〜#〜] iframe [〜#〜]のコンテンツが同じOriginIFRAME属性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

これにより、ネイティブHTML要素はそのままでAngular Universalとの互換性を維持できます。

1
Yoraco Gonzales

次の方法で問題を解決しました。

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

または、現在有名なTypeScriptの回避策を使用します。

iframe['contentWindow']
0
SoEzPz