javascript: прослушивание событий postMessage из определенного iframe

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

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

6 ответов


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


если 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-адресом и задает ему высоту.


вы должны слушать на глобальном 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
    }

    // ...
});

вы могли бы использовать 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 имеют уникальный домен.


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


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