2013-04-28 66 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 
    } 

    // ... 
});