Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling components function from iframe

Tags:

angular

iframe

I have an iframe in my window and I added new buttons to it with jquery. Before migrating to angular2, i was using parent.SampleFunction() to call parent's functions from iframe. Now parent is an angular component and it does not work.

export class AppComponent {

 // use jquery to find the iframe and put a button into it
 addButtonToIFrame() {
     ...
     let buttonHtml = "<button onClick='parent.SampleFunction()'></button>"
     ...
 }

 SampleFunction() {
  ...
 } 

}

How should I change onclick function to access parent?

like image 496
Cory Avatar asked Jan 12 '17 14:01

Cory


1 Answers

Same Origin Iframe

You can safely access the window.parent object, so you just need to put your SampleFunction in the global window object.

export class AppComponent {

 constructor(){
  (<any>window).SampleFunction= this.SampleFunction.bind(this);
 }

 // use jquery to find the iframe and put a button into it
 addButtonToIFrame() {
     ...
     let buttonHtml = "<button onClick='parent.SampleFunction()'></button>"
     ...
 }

 SampleFunction() {
  ...
 }
} 

If you have multiple instances of same class and your SampleFunction deals with the component state, you might need to create random name for your SampleFunction.

You could also use the PostMessage API which should be a more flexible alternative.

PostMessage API

If you are dealing with iframe from another domain, you can use the PostMessage API :

script inside iframe

window.parent.postMessage({foo:"foo"});

component inside parent

export class AppComponent {

 @HostListener("window:message",["$event"])
 SampleFunction($event:MessageEvent) {
  if (event.origin !== "protocol://my-expected-domain.tdl:port")
    return;
  console.log($event.data)// {foo:"foo"}
 }

} 

Of course you have to check the event.origin against the actual domain of the iframe.

like image 155
n00dl3 Avatar answered Nov 02 '22 01:11

n00dl3