JavaScript: accedere al DOM dell'elemento iframe

Short link

Cercando di modificare il comportamento predefinito del link contenuto all'interno di un bottone di Twitter (quello con ID b) con jQuery mi sono imbattuto nello spinoso problema dell'accesso al DOM contenuto in un elemento iframe. Cercando sul Web mi sono imbattuto in questo articolo che risponde in pieno alla nostra domanda fornendo una soluzione cross-browser. Vediamola nei dettagli.

Come funziona iframe

Quando si utilizza questo elemento per caricare una pagina remota, il browser creare un documento del tutto nuovo all'interno della pagina ospite. Quindi nella console DOM vedremo qualcosa come:


<iframe src="http://sitoremoto.it/pagina.html" id="iframe" name="test-frame">
	<!DOCTYPE html>
	<html>
		<head></head>
		<body>
			<p id="test">Test</p>
		</body>
	</html>
</iframe>

L'elemento con ID test viene visualizzato nella pagina corrente, ma è ubicato nella struttura DOM della pagina remota, non in quella della pagina corrente. Quindi scrivere:


var test = document.getElementById('test');

non funziona, perchè l'interprete JavaScript cerca nel DOM della pagina corrente, non in quello della pagina remota.

Le soluzioni

La prima soluzione proposta è quella di utilizzare l'attributo name dell'elemento all'interno della collezione DOM Level 0 chiamata frames:


var test = window.frames['test-frame'].document.getElementById('test');

Purtroppo l'attributo name crea dei problemi di validazione, quindi ecco la seconda soluzione:


var iframe = document.getElementById('iframe');
var docIframe = (iframe.contentWindow || iframe.contentDocument);

if(docIframe.document) {

	docIframe = docIframe.document;

}

var test = docIframe.getElementById('test');

console.log(test.firstChild.nodeValue); // 'Test'

In questo caso usiamo l'ID dell'elemento e possiamo superare la validazione.