2013-04-28 12 views
8

ページに複数のiframeがあります。今度は、すべてのiframeからのメッセージを取得するページのイベントリスナーを1つ持っています(message)。私はiframeにメッセージが来ることを知るための回避策を持っています。javascript:特定のiframeからpostMessageイベントを受け取ります

各iframeごとにイベントリスナーを個別に作成したいと考えています。これは可能ですか?

+0

はそれが可能だとは思いません。ウィンドウはどこからでも 'message'イベントを受け取ることができます。回避策がある場合は、おそらく問題ありません。 –

+1

ちょうど好奇心のために、あなたはあなたの回避策をどのようにしていますか? – zer00ne

答えて

1

いいえ、不可能です。最善の方法は、受信したメッセージをメッセージ送信者の元に基づいてヘルパーハンドラにルーティングする単一のハンドラを用意することです。各IFRAMEのsrc属性が一意である場合

+1

各iframeに一意のname属性を設定することで行うことができます。inside iframe window.nameはiframeの名前で、postMessageで送信することができます。 –

7

その後、あなたはこれを試すことができます。親に

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()を使用してiframeの親へのURL。親はそのイベントを待ち受け、そのURLでiframeをつかんで高さを設定します。

+0

あなたの答えがOPの質問に非常にうまく対応しているかどうかはわかりませんが、あなたのコードは個人的に役立ちました。 – zer00ne

+0

私は高さのビットを取り除くことができたと思います。やりましょうか? –

+0

私はOPがiframeごとに個々のeventListenersを必要としていると思っていますが、同じイベントであるためiframeをリッスンしている複数のeventListenerが重複しているので役に立たないでしょう。重複するイベントリスナーは、いずれかの重複が無視される間に1つだけ動作するため、スパイスを無駄にします。 – zer00ne

1

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

'e.originalEvent.origin'はシリアル化された文字列の結果としてURLを返しますか?私はjQueryに精通しているわけではなく、jQueryの便宜のためにラップアップされたobjectEvent内の特定のプロパティを返します。したがって、 'origin'は実際にはイベントの' location.protocol + location.hostname'を表示できますか? – zer00ne

+0

例は機能していません、e.dataは未定義です。 –

0

メッセージがどこから来たのかを検出する方法の1つは、iframeがフォーカスされているかどうか、iframeが表示されている特定のシナリオを確認することです。

0

実際は可能です。各iframeに一意の名前属性を追加します。 iframeの名前がcontentWindowに渡されます。内側のiframe window.nameはiframeの名前で、簡単に投稿メッセージで送信できます。

0

あなたはwindowオブジェクトのグローバルmessageイベントをリッスンする必要がありますが、MessageEventsourceプロパティを使用して、ソースはiframeを絞り込むことができます。

例:

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

    // ... 
}); 
関連する問題