2013-04-28 65 views
8

我在頁面中有多個iframe。現在我有一個message事件監聽器,它從所有的iframe獲取消息。我有一個解決方法來知道哪個iframe的消息即將到來。javascript:偵聽來自特定iframe的postMessage事件

我想分別爲每個iframe製作事件監聽器。這可能嗎?

+0

不要認爲這是可能的。該窗口可以接收來自任何地方的「消息」事件。如果你有一個解決方法,那可能是好的。 – 2013-04-28 19:50:14

+1

只是爲了好奇,你如何解決你的問題? – zer00ne 2015-12-02 01:25:55

回答

1

不,這是不可能的。你可以做的最好的事情是擁有一個處理程序,它根據消息發送者的來源將收到的消息路由到助手處理程序。

+1

可以通過爲每個iframe設置唯一的名稱屬性來完成。然後在iframe中window.name是iframe的名稱,可以使用postMessage發送。 – 2017-02-07 13:15:40

7

如果每個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()的iframe父級網址。父母然後監聽該事件,抓取具有該URL的iframe並將高度設置爲該值。

+0

儘管我不確定你的回答是否很好地解決了OP的問題,但我發現你的代碼對我個人很有用 - 謝謝。 – zer00ne 2015-12-02 01:28:45

+0

我想我可以去掉高度位。我可以嗎? – 2015-12-02 04:52:22

+0

我認爲OP只需要爲每個iframe設置單獨的eventListeners,但是它將毫無用處,因爲在任何iframe上偵聽的多個eventListeners會重複,因爲它是相同的事件。任何重複的eventListeners都只是浪費香料,因爲只有一個會工作,而任何重複將被忽略。 – zer00ne 2015-12-02 17:35:06

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,所有我發現,它是返回一個objectEvent內的某些屬性,爲了jQuery的方便而封裝了它。所以'origin'實際上可以顯示一個事件的'location.protocol + location.hostname'? – zer00ne 2015-12-02 17:26:03

+0

示例不起作用,e.data未定義。 – 2016-05-10 17:24:24

0

檢測消息來自何處的一種方法是通過檢查哪些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 
    } 

    // ... 
});