Javascript: слушать события postMessage из определенного iframe

У меня есть несколько iframes на странице. Теперь у меня есть один message прослушиватель событий для страницы, который получает сообщения из всех фреймов. У меня есть обходной путь, чтобы узнать, из какого iframe появится сообщение.

Я хотел бы делать прослушиватели событий для каждого iframe отдельно. Возможно ли это?

Ответ 1

Нет, это невозможно. Лучше всего вы можете сделать один обработчик, который направляет полученные сообщения вспомогательным обработчикам на основе происхождения отправителя сообщения.

Ответ 2

Вы должны прослушивать глобальное событие message объекта window, но вы можете отфильтровать исходный iframe, используя source свойство MessageEvent.

Пример:

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

    // ...
});

Ответ 3

Если атрибут src для каждого iframe уникален, вы можете попробовать следующее:

У ребенка:

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();

У родителя:

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

Ребенок отправляет высоту и URL-адрес родителям iframe с помощью postMessage(). Затем родитель прослушивает это событие, захватывает iframe с этим URL-адресом и устанавливает для него высоту.

Ответ 4

Собственно, вы можете. Добавьте уникальный атрибут имени для каждого iframe. Имя iframe передается в contentWindow. Таким образом, внутри iframe window.name является именем iframe, и вы можете легко отправить его в сообщение сообщения.

Ответ 5

Вы можете использовать e.originalEvent.origin для идентификации iframe.

В дочернем элементе iframe:

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

На родительском элементе iframe:

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);

Итак, origin содержит протокол и домен, из которых был запущен postMessage(). Он не включает URI. Этот метод предполагает, что все iframes имеют уникальный домен.

Ответ 6

Одним из способов обнаружения, откуда приходит сообщение, является проверка того, какой iframe сфокусирован, или для моего конкретного сценария, который отображается iframe.