2013-04-28 13 views
8

Ho più iframe in una pagina. Ora ho un listener di eventi message per la pagina, che riceve i messaggi da tutti gli iframe. Ho una soluzione per sapere da quale iframe il messaggio sta arrivando.javascript: ascolta eventi postMessage da iframe specifico

Vorrei organizzare separatamente gli ascoltatori di eventi per ciascun iframe. È possibile?

+0

non credo che sia possibile. La finestra può ricevere eventi 'message' da qualsiasi luogo. Se hai una soluzione, probabilmente è ok. –

+1

Solo per motivi di curiosità, come fai a risolvere il tuo problema? – zer00ne

risposta

1

No, non è possibile. La cosa migliore che puoi fare è avere un unico gestore che instradi i messaggi ricevuti agli helper handler in base all'origine del mittente del messaggio.

+1

Può essere fatto impostando un attributo nome univoco per ogni iframe.Quindi all'interno di iframe window.name è il nome dell'iframe e può essere inviato con postMessage. –

7

Se l'attributo src di ogni iframe è unico allora si può provare questo:

sul bambino:

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(); 

sul genitore:

$(window).on("message", function(e) { 
    var data = e.originalEvent.data; 
    $('iframe[src^="' + data.location + '"]').css('height', data.height + 'px'); 
}); 

Il bambino manda è all'altezza e URL al genitore iframe utilizzando postMessage(). Il genitore quindi ascolta quell'evento, prende l'iframe con quell'URL e ne imposta l'altezza.

+0

Anche se non sono sicuro che la tua risposta risponda molto bene alla domanda dell'OP, trovo il tuo codice utile per me personalmente - alzato, grazie. – zer00ne

+0

Immagino di poter togliere i bit dell'altezza. Dovrei? –

+0

Penso che l'OP voglia semplicemente singoli eventListeners per ogni iframe, ma sarebbe inutile dato che più eventListener che ascoltano su qualsiasi iframe sarebbe un duplicato perché è lo stesso evento. Eventuali EventListeners duplicati sono solo delle spezie sprecate poiché solo uno funzionerà mentre eventuali duplicati verranno ignorati. – zer00ne

1

È possibile utilizzare e.originalEvent.origin per identificare l'iframe.

sul bambino iframe:

window.parent.postMessage({ 
    'msg': 'works!' 
}, "*"); 

sul genitore 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); 

Così origin contiene il protocollo e il dominio da cui il postMessage() è stato licenziato dalla. Non include l'URI. Questa tecnica presuppone che tutti gli iframe abbiano un dominio univoco.

+1

'e.originalEvent.origin' restituisce un URL come risultato di una stringa serializzata? Non sono così familiare con jQuery e tutto quello che trovo su questo è che restituisce alcune proprietà all'interno di un objectEvent che è stato archiviato per comodità da jQuery. Quindi 'origin' può effettivamente mostrare un' location.protocol + location.hostname' di un evento? – zer00ne

+0

L'esempio non funziona, e.data non è definito. –

0

Un modo per rilevare da dove proviene il messaggio è controllare quale iframe è focalizzata o per il mio scenario specifico che iframe è visibile.

0

In realtà è possibile. Aggiungi un attributo nome univoco a ciascun iframe. il nome iframe viene passato alla contentWindow. Quindi dentro iframe window.name è il nome dell'iframe e puoi facilmente inviarlo in un messaggio.

0

devi ascoltare sul message evento globale dell'oggetto window, ma è possibile filtrare l'iframe fonte utilizzando la proprietà source di MessageEvent.

Esempio:

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

    // ... 
}); 
Problemi correlati