5

I would like to have an iframe in a Lightning component.

I, first, tried to create a lightning:container as this:

  <aura:attribute name="url"    
                  type="String" 
                  default="https://www.google.com" 
  />

  <lightning:container src="{! v.url}" 
                       onerror="{! c.onError }" 
                       onmessage="{! c.onMessage }" />

but according to documentation:

lightning:container allows you to use an app developed with a third-party framework, such as AngularJS or React, in a Lightning component. Upload the app as a static resource.

So I decided to use an iframe as this:

<iframe
  id="iframe"
  aura:id="iframe"
  style="{! v.style }"
  src="{! v.url}"
  width="{! v.width }"
  height="{! v.height }"
  scrolling="{! v.scrolling }"
  onerror="{! c.onError }"
  frameborder="{! v.frameBorder }"
  sandbox="{! v.sandbox }"
/>

And setting up the eventListener on message during Lightning Component initialisation :

  function(component, event, helper) {
    const iframe = component.find('iframe');
    console.log(iframe);

    iframe.addEventHandler('message', (event) => {
      console.log('received message');
      console.log(event);
    }, false); // It works

    const frame = document.getElementById('iframe');
    console.log(frame); // null
    /*
    frame.addEventListener('message', (event) => {
      console.log('received message');
      console.log(event);
    }, false)

    frame.postMessage({ test: 'test' }, '*');
    */
    console.groupEnd();
  }

This works (receiving message) but I can not do component.find('iframe').postMessage(). Instead I tried to perform a querySelector on id but I am not able to get the HTML Element to perform a post message.

Do you have any workaround to do so ? (Version 41.0).

Lightning Container Documentation

1 Answer 1

2

HTML elements are rendered as aura:html components, so you need to get elelment first:

var iframe = component.find('iframe').getElement();

should return the html element, but be aware, that it will only be available after the component is rendered, as described here.

In case you are using a init handler I would suggest using render instead (docu):

<aura:handler name="render" value="{!this}" action="{!c.doStuff}"/>

So your action could call it like this:

iframe.getElement().postMessage({ test: 'test' }, '*');
5
  • getElement does not return anything I will then try in after rendering function.
    – Simonp
    Dec 7, 2017 at 11:12
  • @SimonPlacentino updated my answer with a render handler.
    – itsmebasti
    Dec 7, 2017 at 11:24
  • iframe.getElement().postMessage({ test: 'test' }, '*'); in the render handler leads to an infinite loop. Someone could confirm me that doing component.find('iframe').addEventHandler('message') and component.find('iframe').getElement().addEventListener('message') is equivalent because handled by Lightning ?
    – Simonp
    Dec 7, 2017 at 12:31
  • @SimonPlacentino Where does the loop come from? were you able to debug anything? The Handler/Listener thing seems to be another question.
    – itsmebasti
    Dec 7, 2017 at 16:35
  • 1
    forget about this. What I did: onInit of component, dynamically create the iFrame with $A.createComponent and addEventListener('message') on my current window object (the only way for me to receive a message): and it works. Thank you anw
    – Simonp
    Dec 8, 2017 at 7:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .