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

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' }, '*');
  • getElement does not return anything I will then try in after rendering function. – Simon Placentino Dec 7 '17 at 11:12
  • @SimonPlacentino updated my answer with a render handler. – Basti Dec 7 '17 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 ? – Simon Placentino Dec 7 '17 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. – Basti Dec 7 '17 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 – Simon Placentino Dec 8 '17 at 7:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.