Flash ExternalInterface, der Internet Explorer und JavaScript Calls
3. April 2009, 07:21 UhrMan stößt ja immer dann auf Browserbugs, wenn man sie am wenigsten brauchen kann, wie auch in diesem Fall.
Wir sollten einen blätterbaren Flash-Katalog per JavaScript und DIV-Layer in eine Webseite einbauen. Den Flash-Katalog sollte man ein- und ausblenden können und außerdem von der HTML-Seite aus per JavaScript auf eine bestimmte Seite im Katalog springen können.
Ist ja alles nicht so dramatisch, schließlich gibt es seit Flash 8 das wunderbare ExternalInterface, mit dem man Flash dazu bringt, auf JavaScript-Funktionen zu hören.
Leider macht der Internet Explorer an dieser Stelle einmal mehr was er will und nicht, was korrekt wäre.
Wenn nämlich ein per JavaScript eingebundenes Flash den Fokus bekommt und danach der Container auf visible=”hidden” gesetzt wird, findet der IE keinen der per ExternalInterface definierten Funktionen mehr.
Zum Testen dieses Phänomens baue man sich eine kleine Flash-Datei mit einem TextFeld, das den Instanznamen “debug_txt” trägt und füge folgenden AS2-Code hinzu (AS3 ist von dem Problem allerdings ebenso betroffen):
var i : Number = 1;
ExternalInterface.addCallback("jsFlashDebugMsg", this, flashDebugMsg);
function flashDebugMsg ( msg : String ) : Void
{
debug_txt.text = i + msg + "\n" + debug_txt.text;
i++;
}
Nun baut man mit z.B. SWFObject dieses Flash in einen Container ein:
<script language="JavaScript" src="swfobject.js" />
<div id="flashcontainer">
In diesen Container wird das SWF geladen
</div>
<script type="text/javascript">
var so = new SWFObject("test.swf", "onlinekat", "200", "200", "8", "#FFFFFF");
so.addParam("allowScriptAccess", "sameDomain");
so.write("flashcontainer");
</script>
Nun benötigt man noch eine Funktion, um das Flash ein- und auszublenden und einen entsprechenden Link dafür:
<script language="JavaScript">
var isShown = false;
function showHide()
{
if ( isShown )
{
isShown = false;
window.document.getElementById('flashcontainer').style.visible = "hidden";
}
else
{
isShown = true;
window.document.getElementById('flashcontainer').style.visible = "visible";
}
}
</script>
<input type="button" value="Show / Hide" onClick="javascript:showHide()" />
Um das Ganze nun gut verfolgen zu können, noch einen kleinen Debugger bauen, der jede Sekunde prüft, ob die Funktion “jsFlashDebugMsg” noch verfügbar ist:
<script language="JavaScript">
var debugWindow;
debugWindow = window.open("", "_blank", "width=300,height=200,statusbar=no,locationbar=no,menubar=no,scrollbars=yes");
debugWindow.document.write('Debug-Console');
function debug( msg )
{
debugWindow.document.write( '
' + msg );
}
setInterval( function() { debug( window.document.getElementById('flashcontent').jsFlashDebugMsg ); }, 1000 );
</script>
Nun kann man folgendes feststellen:
Solange man den Fokus nicht auf das SWF gesetzt hat (also darauf geklickt hat), wird die Funktion ordentlich gefunden. Selbst wenn man den Fokus darauf gesetzt hat, ist sie immer noch vorhanden, wenn man danach aber den Container per visible=”hidden” versteckt, bekommt man vom IE nur noch ein “undefined” zurück.
Lösung des Problems ist ganz einfach: Statt style.visible = “hidden” nehme man style.left = -4000 und setzt damit das SWF aus dem sichtbaren Bereich.
Dann klappt’s auch mit dem IE.