Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get iframe by message event

I have several iframes with same origin (but different pathnames) on the page.
Every iframe emits message event through postMessage.
Parent window listens these events:

window.addEventListener('message', function(event) {
  /* Get iframe element by event */
});

I want to get source iframe element for every event.

The important limitation is that I have no access to event.source.contentWindow because of cross-origin.

UPD: answer below

like image 362
Legotin Avatar asked May 21 '18 20:05

Legotin


People also ask

How do I post a message in iframe?

If sending a message to a document in an iframe, first get a reference to the iframe and then its contentWindow property as shown below. If sending a message from the iframed document to the containing document, the parent keyword provides a reference. If sending a message to a window opened using the window.

How do you communicate between two iframes?

Communicating directly between iframes is also possible by combining window. parent with target as defined above. In conclusion, the postMessage method is a more dynamic alternative to the single DOM, better suited if you load multiple pages in one iframe, but not always easier and it still requires the use of the DOM.

What is postMessage?

postMessage() is a safe way to send messages between windows in different domains or origins. One can also post to an IFrame. The data being sent is serialized using the structured clone algorithm and will accept almost any type of simple or complex data.


1 Answers

The solution is to compare event.source and iframe.contentWindow:

function getFrameByEvent(event) {
  return [].slice.call(document.getElementsByTagName('iframe')).filter(function(iframe) {
    return iframe.contentWindow === event.source;
  })[0];
}

Here's more modern version:

function getFrameByEvent(event) {
  return Array.from(document.getElementsByTagName('iframe')).filter(iframe => {
    return iframe.contentWindow === event.source;
  })[0];
}
like image 164
Legotin Avatar answered Oct 15 '22 04:10

Legotin