سؤال

I have multiple iframes in a page. Now I have one message event listener for the page, which gets the messages from all of the iframes. I have a workaround to know from which iframe the message is coming.

I would like to make event listeners for each iframe separately. Is this possible?

هل كانت مفيدة؟

المحلول 7

No, it's not possible. Best you can do is to have a single handler that routes received messages to helper handlers based on the origin of the message sender.

نصائح أخرى

You must listen on the global message event of the window object, but you can filter the source iframe using the source property of MessageEvent.

Example:

const childWindow = document.getElementById('test-frame').contentWindow;
window.addEventListener('message', message => {
    if (message.source !== childWindow) {
        return; // Skip message in this event listener
    }

    // ...
});

If the src attribute of each iframe is unique then you can try this:

On the child:

function sendHeight() {
  // sends height to parent iframe
  var height = $('#app').height();
  window.parent.postMessage({
    'height': height,
    'location': window.location.href
  }, "*");
}

$(window).on('resize', function() {
  sendHeight();
}).resize();

On the parent:

$(window).on("message", function(e) {
    var data = e.originalEvent.data;
    $('iframe[src^="' + data.location + '"]').css('height', data.height + 'px');
});

The child sends it's height and URL to the iframe parent using postMessage(). The parent then listens for that event, grabs the iframe with that URL and sets the height to it.

Actually you can. Add a unique name attribute to each iframe. iframe name is passed down to the contentWindow. So inside iframe window.name is the name of the iframe and you can easily send it in post message.

You could use e.originalEvent.origin to identify the iframe.

On the iframe child:

window.parent.postMessage({
  'msg': 'works!'
}, "*");

On the iframe parent:

Javascript

window.addEventListener('message', function(e) {
  console.log(e.origin); // outputs "http://www.example.com/"
  console.log(e.data.msg); // outputs "works!"
  if (e.origin === 'https://example1.com') {
    // do something
  } else if (e.origin === 'https://example2.com'){
    // do something else
  }
}, false);

jQuery

$(window).on('message', function(e) {
  ...
}, false);

So origin contains the protocol and domain from which the postMessage() was fired from. It does not include the URI. This technique assume all iframes have a unique domain.

One way of detecting where the message came from is by checking which iframe is focused or for my specific scenario which iframe is visible.

I implemented an iframe proxy. Iframe with in an iframe ( nesting them ). Each iFrame proxy creates it's own unique I'd. Than every message that is sent from child iframe to parent is gets an added field of the iframe proxy I'd. In the parent you then route every message from the iframeproxy to it's dedicated handler. This mechanism separate iframes perfectly

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top