1ページに複数のiframeがあります。これで、ページにmessage
イベントリスナーが1つあり、すべてのiframeからメッセージを取得します。メッセージがどのiframeから送信されているかを知るための回避策があります。
Iframeごとに個別にイベントリスナーを作成したいと思います。これは可能ですか?
いいえ、できません。最善の方法は、メッセージ送信者の発信元に基づいて、受信したメッセージをヘルパーハンドラーにルーティングする単一のハンドラーを用意することです。
message
オブジェクトのグローバルwindow
イベントをリッスンする必要がありますが、 source
プロパティを使用してソースiframeをフィルタリングできます MessageEvent
。
例:
const childWindow = document.getElementById('test-frame').contentWindow;
window.addEventListener('message', message => {
if (message.source !== childWindow) {
return; // Skip message in this event listener
}
// ...
});
各iframeのsrc
属性が一意である場合は、次のことを試すことができます。
子供について:
_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');
});
_
子は、postMessage()
を使用して、その高さとURLをiframeの親に送信します。次に、親はそのイベントをリッスンし、そのURLでiframeを取得して、高さを設定します。
実際にできます。各iframeに一意の名前属性を追加します。 iframe名はcontentWindowに渡されます。したがって、iframe内のwindow.nameはiframeの名前であり、投稿メッセージで簡単に送信できます。
_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は含まれていません。この手法では、すべてのiframeに一意のドメインがあることを前提としています。
メッセージの送信元を検出する1つの方法は、どのiframeがフォーカスされているか、または特定のシナリオではどのiframeが表示されているかを確認することです。