2013-04-28 2 views
8

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

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

+0

Не думаю, что это возможно. Окно может принимать события «сообщения» из любого места. Если у вас есть обходной путь, возможно, это нормально. –

+1

Просто ради любопытства, как вы делаете свое обходное решение? – zer00ne

ответ

1

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

+1

Можно сделать, установив уникальный атрибут имени для каждого iframe.Затем внутри iframe window.name является именем iframe и может быть отправлено с postMessage. –

7

Если атрибут каждого фрейма 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'); 
}); 

Ребенок посылает его высота и URL-адрес родителя iframe с использованием postMessage(). Затем родитель прослушивает это событие, захватывает iframe с этим URL-адресом и устанавливает для него высоту.

+0

Хотя я не уверен, что ваш ответ очень хорошо затрагивает вопрос OP, я считаю, что ваш код полезен для меня лично, - спасибо, спасибо. – zer00ne

+0

Думаю, я мог бы вырезать биты высоты. Должен ли я? –

+0

Я думаю, что OP просто хочет отдельных eventListeners для каждого iframe, но это было бы бесполезно, поскольку несколько eventListeners, прослушивающих любой iframe, были бы дубликат, потому что это одно и то же событие. Любые дублированные eventListeners - это просто потерянная специя, поскольку только один будет работать, в то время как любые дубликаты будут проигнорированы. – zer00ne

1

Чтобы определить iframe, вы можете использовать e.originalEvent.origin.

На 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 имеют уникальный домен.

+1

Вызывает ли 'e.originalEvent.origin' URL-адрес из-за того, что он является сериализованной строкой? Я не так хорошо знаком с jQuery, и все, что я нахожу, это то, что он возвращает определенные свойства внутри объекта Object, который был завершен для удобства jQuery. Итак, 'origin' на самом деле может показать событие' location.protocol + location.hostname 'события? – zer00ne

+0

Пример не работает, e.data не определен. –

0

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

0

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

0

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

    // ... 
}); 

 Смежные вопросы

  • Нет связанных вопросов^_^