Teil von SELFHTML aktuell Teil von Artikel Teil von Programmiertechnik

LiveConnect
zwischen JavaScript
und Flash-ActionScript

nach unten Gernot Back
nach unten Allgemeines
nach unten Die Schnittstelle HTML / Flash
nach unten JavaScript beeinflusst ActionScript
nach unten getURL-Aufruf von JavaScript durch ActionScript
nach unten FSCommand an JavaScript durch ActionScript
nach unten Kommunikation zweier Flash-Filme via FSCommand und JavaScript
nach unten Kommunikation zweier Flash-Filme via getURL-Aufruf von JavaScript
nach unten Die Schnittstelle JavaScript / Flash
nach unten Browserunterstützung
nach unten Beispiele downloaden

Gernot Back

E-Mail: E-Mail gernotback@arcor.de
Homepage-URLs: deutschsprachige Seite http://www.sprachlernspiele.de/
deutschsprachige Seite http://www.akadaf.de/

Bei Fragen zu diesem Beitrag bitte den Autor des Beitrags kontaktieren!

nach obennach unten

LiveConnect: Allgemeines

Flash-Plugins gehören inzwischen zur vorinstallierten Grundausstattung jedes Browsers. Die darin abgespielten Anwendungen sind - anders als bei JavaScript - weitgehend plattformunabhängig. Andererseits benötigen sie mehr Speicherplatz und Ladezeit.

Einfache Animationen lassen sich in Flash auch ganz ohne Skripte mit sogenannten "Tweens" erstellen, die dann sogar auch in andere Formate, wie animierte Gifs, Mpegs, Quicktime- oder sonstige Filmformate exportiert werden können. Spätestens wenn Interaktion gefragt ist, ist aber auch in einem Flash-Film ein Scripting erforderlich. Flash-ActionScript und JavaScript sind dabei, sowohl was die Verwendung als auch was die Syntax angeht, gar nicht so unterschiedlich. Ein Wechsel zwischen beiden Skriptsprachen sollte daher in der Regel nicht sonderlich schwer fallen.

Durch geschickte Kombination von Flash und JavaScript lassen sich ggf. die Stärken beider Arten von Anwendungen maximieren und deren Schwächen minimieren. Schwierig wird dies allerdings, wenn JavaScript und Flash-ActionScript zusammenwirken sollen: Eine Kette ist nun mal immer nur so stark wie ihr jeweils schwächstes Glied.

Die sogenannte "LiveConnect"-Kommunikation zwischen beiden Skriptsprachen funktioniert grundsätzlich in beide Richtungen. D.h.: Sie haben über JavaScript Zugriff auf ActionScripts und damit das Verhalten eines eingebetteten Flash-Films. Umgekehrt können Sie mittels ActionScript aus einem Flash-Film heraus JavaScript-Funktionen aufrufen. Über den Umweg von JavaScript können deshalb sogar auch mehrere Flash-Filme miteinander kommunizieren.

Leider ist LiveConnect nicht in allen Browsern implementiert: Insbesondere am Mac und unter Linux (sowie bei Netscape 6 und älteren Mozilla-Versionen auch am Windows-PC) läuft LiveConnect entweder gar nicht oder nur in einer Richtung. Eine (allerdings nicht vollständige) Übersicht, in welchen Browsern LiveConnect funktioniert und in welchen ggf. nur eingeschränkt oder überhaupt nicht, finden Sie im Abschnitt:

nach unten Browserunterstützung.

nach obennach unten

Die Schnittstelle HTML / Flash

Wer seinen Film durch einfachen Klick aus der Flash-Autorenumgebung heraus "veröffentlicht", dem generiert das Programm neben dem eigentlichen Film als SWF-Datei auch eine HTML-Datei. Erstere ist dann in letztere bereits fix und fertig eingebunden. Vorausgesetzt man hat im Autorenprogramm auch vorher alle Grundeinstellungen (ggf. auch die für LiveConnect) richtig gewählt, so funktioniert das dann auch alles prima und - sehr praktisch!

Die Sache hat nur einen Haken. Da Flash mit Rücksicht auf ältere Netscape-Browser bei der Einbettung des Films auf das Embed-Element zurückgreift, das nicht zum HTML-Standard gehört, darf eine solche Seite keinen W3C-Stempel tragen.

Drew McLellan (bekannt als Autor eines Entwicklerhandbuchs für Dreamweaver) hat das keine Ruhe gelassen. Seiner Tüftelei ist es zu verdanken, dass die Entwicklerwelt seit November 2002 über eine zweite Methode verfügt, Flash-Filme so in HTML-Seiten einzubinden, dass sie sich auch in älteren Netscape-Browsern darstellen lassen, und - kaum zu glauben - diese Methode ist dabei auch noch konform mit den strengen Regeln des W3C.

Im folgenden Beispiel ist ein und derselbe Flash-Film zweimal eingebunden; einmal nach der herkömmlichen Methode und zusätzlich einmal nach der validen Methode. Wie man sich anhand des Anzeigebeispiels leicht selbst überzeugen kann, funktionieren beide Methoden zuverlässig mit unterschiedlichsten Browsern und auf unterschiedlichsten Plattformen.

Natürlich ist auch die valide Einbettungsvariante nicht frei von Nachteilen: Will man z.B. das Streaming des Flash-Films für Mozilla und neuere wie ältere Netscape-Browser sicherstellen, so ist dies zwar grundsätzlich auch möglich, jedoch nur über verschlungene Umwege. Wer sich für die näheren Details hierzu interessiert, sei an dieser Stelle auf den Originalartikel von Drew McLellan verwiesen.

englischsprachige Seite http://www.alistapart.com/articles/flashsatay.

Was das Thema LiveConnect angeht, das erst in den weiteren Beispielen relevant werden wird, so verhalten sich beide Varianten der Einbettung widersprüchlich: Je nach Plattform (Konstellation von Browser und Betriebssystem) läuft insbesondere die Kommunikaion in den Flash-Film hinein mal nur mit dieser, mal nur mit jener Variante.

Beispiel Einbindung in HTML:

Popup-Seite Anzeigebeispiel: So sieht's aus

<html><head><title>Flash-Plugin-Einbettung</title>
</head>
<body>

<table cellpadding="10" cellspacing="0">
<tr>
 <th colspan="2" >Zwei Arten der Einbettung von Flash-Filmen
 in ein HTML-Dokument:</th>
</tr>
<tr>
 <td>
<!--Anfang herkömmliche Flasheinbettung-->
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
 codebase=
 "http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0"
 WIDTH="45" HEIGHT="90" id="Demo" ALIGN="">
 <param name="movie" VALUE="Demo.swf">
 <param name="quality" VALUE="high">
 <param name="bgcolor" VALUE="#EEEFEF">
 <param name="swliveconnect" value="true">
 <EMBED src="Demo.swf" quality="high"
           swLiveConnect=true
           bgcolor="#EEEFEF" WIDTH="45" HEIGHT="90"
           NAME="Demo"
           TYPE="application/x-shockwave-flash"
           PLUGINSPAGE="http://www.macromedia.com/go/getflashplayer"></EMBED>
</object>
<!--Ende herkömmliche Flasheinbettung-->
 </td>
 <td>
<!--Anfang W3C-konforme Flasheinbettung-->
<object type="application/x-shockwave-flash" data="Demo.swf"
 WIDTH="45" HEIGHT="90" id="Demo" ALIGN="">
 <param name="movie" VALUE="Demo.swf">
 <param name="quality" VALUE="high">
 <param name="bgcolor" VALUE="#EEEFEF">
 <param name="swliveconnect" value="true">
 <p>Ihr Browser verfügt offensichtlich derzeit nicht über das Flashplugin,
 jedenfalls nicht in der erforderlichen Version.<br>
 Bitte laden Sie es unter folgendem Link herunter.<br>
  <a href="http://www.macromedia.com/go/getflashplayer">
   http://www.macromedia.com/go/getflashplayer</a></p>
</object>
<!--Ende W3C-konforme Flasheinbettung-->
 </td>
</table>

</body>
</html>

Nähere Erläuterungen zu den Unterschieden der beiden Einbettungsarten für Flash-Filme würden den Rahmen dieses Artikels sprengen, bei dem es vornehmlich um das Thema LiveConnect gehen soll.

Diese Unterschiede werden im englischsprachigen Artikel von Drew McLellan en détail erläutert. Deshalb an dieser Stelle nochmals der bereits erwähnte Verweis:

englischsprachige Seite http://www.alistapart.com/articles/flashsatay.

Vgl. zur herkömmlichen Einbettungsvariante auch:

bereichsübergreifende SeiteFlash-Anwendungen als Objekt einbinden.

Als Erläuterung zum Thema LiveConnect ist in obigem Quellcode allerdings Folgendes zu beachten:

Soll JavaScript auf ein ActionScript Einfluss nehmen und dies auch in älteren Netscape-Browsern funktionieren, so gibt es, keine Alternative zum Embed-Element. Umgekehrt scheinen auch FSCommands des ActionScripts an JavaScript in neueren Mozilla- und Netscape-Browsern (ab Version7) auf taube Ohren zu stoßen, wenn etwas anderes als die <embed>-Methode zur Einbindung verwendet wird.

Von den folgenden Anzeigebeispielen für LiveConnect wurden mit Rücksicht auf diese Browser daher nur jene, die mit einem getURL()-Aufruf einer JavaScript-Funktion arbeiten mit der W3C-konformen Einbettungsmethode ohne Embed-Element implementiert. Wem W3C-Konformität wichtiger ist als die Funktionalität im Einzelfall, der mag sich aber dennoch gerne auch bei den anderen Beispielen für die Variante ohne Embed-Element entscheiden.

Damit ein Flashfilm durch Javascript steuerbar wird, ist es in einigen Browsern erforderlich, dass das Object-Element das <param>--Tag <param name="swliveconnect" value="true"> enthält. Wenn man sich zur herkömmlichen Einbettung entschließt, so ist es darüber hinaus entscheidend, dass im <embed>-Tag die Anweisung swLiveConnect="true" steht.

Im oben gezeigten Beispiel, bei dem es schlicht um die beiden Einbettungsarten als solche geht, könnte man auf diese Anweisungen zu LiveConnect eigentlich verzichten, ja streng genommen sollte hier sogar jeweils false stehen; Eine LiveConnect-Kommunikation findet hier ja noch gar nicht statt. Die Anweisungen <param name="swliveconnect" value="true"> bzw. swLiveConnect="true" scheinen aber hier auch nicht zu schaden.

Neben der Schnittstelle HTML / Flash verdient auch die Schnittstelle JavaScript / Flash besondere Aufmerksamkeit. Um den Leser oder die Leserin hier aber nicht allzu sehr auf die Folter zu spannen, wird dieses Problem erst am Ende dieses Artikels behandelt:

nach unten Die Schnittstelle JavaScript / Flash

Im Folgenden soll es zuerst darum gehen, LiveConnect anhand von fünf Beispielen in Aktion zu erleben.

nach obennach unten

JavaScript beeinflusst ActionScript

JavaScript kann in einem auf einer HTML-Seite eingebundenen Flash-Film über LiveConnect allgemeine Flash-Methoden aufrufen. Das folgende Beispiel soll die Funktionsweise der Methode SetVariable(Variablenname, Wert) demonstrieren.

Ein Anwendungsbeispiel für den Aufruf zweier weiterer allgemeiner Flash-Actionscript-Methoden finden Sie weiter unten:

nach unten Kommunikation zweier Flash-Filme via FSCommand und JavaScript

Eine Liste der allgemeinen Flash-ActionScript-Methoden, die mit JavaScript direkt aufrufbar sind, finden Sie unter

englischsprachige Seite http://www.macromedia.com/support/flash/publishexport/scriptingwithflash/scriptingwithflash_03.html.

Beispiel Einbindung in HTML:

Popup-Seite Anzeigebeispiel: So sieht's aus

<html><head><title>LiveConnect</title>
<script type="text/javascript" src="FindeFlash.js"></script>
<script type="text/javascript">
<!--
  function wertHolen () {
    if(window.location.search) {
      var wert = window.location.search;
      wert = wert.substring(wert.indexOf('=')+1,wert.length);
      document.forms['tempus'].minut.value=wert;
      uhrStellen();
    }
  }

  function uhrStellen () {
    var minuten = parseInt(document.forms['tempus'].minut.value);
    var zeit = minuten*60*1000;
    //var movie = window.document.EierUhrJSanAS;
    var movie = findeFlash('EierUhrJSanAS');
    if (movie) {
      movie.SetVariable("ende", zeit.toString());
    }
  }
//-->
</script>
</head>
<body onLoad="wertHolen()">

<form name="tempus" action="#" method="get">
<p>Bitte geben Sie eine andere Laufzeit in Minuten ein!</p>
<input type="Text" name="minut" value="" size="3" maxlength="3"> Minuten<br>
<br>
<input type="Submit" name="" value="Uhr stellen">
</form>

<object id="EierUhrJSanAS">
 // Einbettung analog zu einer der beiden Varianten aus Beispiel 1
 // mit entsprechenden Benennungen in ID und/oder NAME
 // und Pfaden zur SWF-Datei "EierUhrJSanAS.swf"
</object>


</body>
</html>

Beispiel Erstellung Flashfilm:

Aktionen für Bild 1 des Ebenennamens skript
_global.ende = 1 * 60 * 1000;
_global.abgel;
 
 

Aktionen für Bild 2 (beschriftet lauf) des Ebenennamens skript
abgel=getTimer();
ratio = abgel/ende;
if (ratio<1) {
        setProperty("sickerM",_height,40*(1-ratio));
        setProperty("haufen",_height,100*ratio);
        setProperty("haufen",_width,200*ratio);
        setProperty("haufen",_y,53+(Math.pow(31,(1-ratio))));
        txt.text=Math.ceil((ende-abgel)/60000);
} else {
        txt.text="0";
}
 
 

Aktionen für Bild 3 des Ebenennamens skript
gotoAndPlay("lauf");
 
 

Aktionen für Bild 50 des Ebenennamens maske
if (_root.ratio<1) {
        gotoAndPlay("anfang");
}
 
 

Aktionen für Bild 51 des Ebenennamens maske
stop();
 
 

Erläuterung:

Bei dem Flash-Film handelt sich um eine Sanduhr, deren Laufzeit über die globale ActionScript-Variable ende im ersten Bild des Films auf eine Minute oder genauer gesagt auf 1*60*1000 Millisekunden voreingestellt wird.

Durch LiveConnect lässt sich diese ActionScript-Variable mittels JavaScript beeinflussen: Auf der HTML-Seite befindet sich neben dem Flash-Film auch ein HTML-Formular mit dem Namen tempus. Darin befindet sich ein Eingabefeld und ein Absendebutton mit der Aufschrift "Uhr stellen". onSubmit, das heißt bei dessen Anklicken ruft sich die Seite selbst komplett neu auf. Dies wird durch die Anweisung action="#" im form-Element bewirkt. Dabei wird die durch den Nutzer eingegebene Wertzuweisung des Eingabefelds namens minut als Zeichenkette an den URI der Seite angehängt. Dies wird durch die Anweisung method="get" im form-Element sichergestellt.
Vgl. hierzu bereichsübergreifende Seite Formularbereich definieren.

Nach dem (Neu-)Aufruf der Seite tritt onLoad, d.h. nachdem auch der Flash-Film zunächst mit seiner Default-Laufzeit von einer Minute neu geladen und gestartet ist, die Funktion wertHolen() in Aktion. Diese liest ggf. aus dem Search-String des URI die gewünschte Laufzeit für die Sanduhr aus und stellt den Wert der ActionScript-Variable ende über die JavaScript-Funktion uhrStellen() im Flash-Film entsprechend anders ein. Da es sich bei ende um eine globale Variable handelt, ist dabei unerheblich, ob sich der Abspielkopf des Flash-Players gerade in Bild 2 oder Bild 3 befindet. Während die Wertevorbelegung in Bild 1 nur einmal zu Beginn erfolgt, werden die Texteinblendung der verbleibenden Minuten und die Skalierung der Sandhäufchen ständig aktualisiert, da das Skript in Bild 3 den Abspielkopf des Players in einer Endlosschleife immer wieder auf Bild 2 zurückschickt. Die Werte sind dabei an das Verhältnis zwischen bereits abgespielter und insgesamt abzuspielennder Zeit gekoppelt.

Die Anweisung zum Stopp der Sanduhr wird aus einem Unterobjekt heraus aufgerufen. Hier ist die Sandgrafik zu einem Sandstrahl von 1 Pixel Breite maskiert und durchläuft zunächst einen Bewegungstween von 50 Bildern (Frames). Das Skript des Bildes 50 der Maskierungsebene entscheidet, je nachdem ob die Spielzeit bereits abgelaufen ist, ob der Abspielkopf zu Bild 51 weiterläuft oder den kompletten Tween von der Bildmarke anfang an erneut durchläuft. In Bild 51 bewirkt ein Skript schließlich den Stopp des Sandrieselns stop();.

nach obennach unten

getURL-Aufruf von JavaScript durch ActionScript

Der Flash-Film kann in umgekehrter Richtung über JavaScript auch mit der HTML-Seite kommunizieren, in die er eingebettet ist. Eine Möglichkeit ist dabei, eine JavaScript-Funktion über die ActionScript-Funktion getURL() aufzurufen

Beispiel Einbindung in HTML:

Popup-Seite Anzeigebeispiel: So sieht's aus

<html><head><title>LiveConnect</title>
<script type="text/javascript">
<!--
  function melden (laufStatus) {
    document.forms['tempus'].ausgabe.value=laufStatus;
  }
//-->
</script>
</head>
<body>

<form name="tempus" action="">
Uhr:
<input type="Text" name="ausgabe" readonly value="" size="6" maxlength="6">
</form>

<object id="EierUhrGetURL">
 // Einbettung analog zu einer der beiden Varianten aus Beispiel 1
 // mit entsprechenden Benennungen in ID und/oder NAME
 // und Pfaden zur SWF-Datei "EierUhrGetURL.swf"
</object>

</body>
</html>

Beispiel Erstellung Flashfilm:

Aktionen für Bild 1 des Ebenennamens skript
_global.ende = 1 * 60 * 1000;
_global.abgel;
getURL("javascript:melden('laeuft')", "_self");
 
 

Aktionen für Bild 51 des Ebenennamens maske
getURL("javascript:melden('fertig')", "_self");
stop();
 
 

Erläuterung:

Im vorliegenden Beispiel ruft ein ActionScript zu Beginn und am Ende der Laufzeit des Flash-Films über getUrl(javascript:(melden(laufStatus), "_self") die entsprechende JavaScript-Funktion in der HTML-Seite auf, in der der Film selbst (_self) platziert ist. Die JavaScripts anderer Zielseiten wie _top, _parent, _blank oder selbstgewählte Frame- oder Fenster-Namen sind ebenfalls ansprechbar. Dies funktioniert allerdings nicht mit dem Browser Opera, der getUrl()-Aufrufe immer auf das eigene Fenster bezieht.

Die JavaScript-Funktion melden(laufStatus) setzt hier den Wert (value) des vom Benutzer nur lesbaren, aber nicht veränderbaren (readonly) input-Elements der Mutterseite auf "laeuft" bzw. "fertig".

nach obennach unten

FSCommand an JavaScript durch ActionScript

Die ActionScript-Funktion getURL() ist eigentlich zum Aufruf anderer Webseiten gedacht. Der Aufruf einer JavaScript-Funktion stellt streng genommen einen Missbrauch dieser Funktion dar. Die von Flash eigentlich hierfür vorgesehene Funktion FSCommand(befehl, Argumente) funktioniert allerdings nicht mit dem Browser Opera und erfordert, was den meist als Standardbrowser benutzten Microsoft-Internet-Explorer angeht, eine etwas umständliche Implementierung. MSIE arbeitet hier nämlich anders als die übrigen Browser mit VB-Script anstelle von JavaScript.

In der Praxis handelt es sich dabei aber nur um ein geringes Problem, da das Flash-Autorenprogramm den VB-Code beim Veröffentlichen des Films automatisch generiert, wenn man die Voreinstellungen dort entsprechend auswählt:

Beispiel Einbindung in HTML:

Popup-Seite Anzeigebeispiel: So sieht's aus

<html><head><title>LiveConnect</title>
<script type="text/javascript">
<!--
  if (navigator.appName && navigator.appName.indexOf("Microsoft") != -1 &&
          navigator.userAgent.indexOf("Windows") != -1 &&
          navigator.userAgent.indexOf("Windows 3.1") == -1) {
     document.write('<script type="text/vbscript"> \n');
     document.write('on error resume next \n');
     document.write('Sub EierUhrFScom_FSCommand(ByVal befehl, ByVal laufStatus)\n');
     document.write('  call EierUhrFScom_DoFSCommand(befehl, laufStatus)\n');
     document.write('end sub\n');
     document.write('</script\> \n');
  }

  function EierUhrFScom_DoFSCommand(befehl, laufStatus) {
    if(befehl=="melden") {
      document.forms['tempus'].ausgabe.value=laufStatus;
    }
  }
//-->
</script>
</head>
<body>

<form name="tempus" action="">
Uhr:
<input type="Text" name="ausgabe" readonly value="" size="6" maxlength="6">
</form>

<object id="EierUhrFScom">
 // Einbettung analog zu einer der beiden Varianten aus Beispiel 1
 // mit entsprechenden Benennungen in ID und/oder NAME
 // und Pfaden zur SWF-Datei "EierUhrFScom.swf"
</object>

</body>
</html>

Beispiel Erstellung Flashfilm:

Aktionen für Bild 1 des Ebenennamens skript
_global.ende = 1 * 60 * 1000;
_global.abgel;
fscommand("melden", "laeuft");
 
 

Aktionen für Bild 51 des Ebenennamens maske
fscommand("melden", "fertig");
stop();
 
 

Erläuterung:

Im Beispiel wird der Seite via Browser- und Versions-Abfrage erforderlichenfalls zunächst über die document.write()-Methode durch JavaScript ein VB-Skript hinzugefügt, das FSCommand für MSIE implementiert.

Die JavaScript-Funktion, die den FSCommand ausführt, muss dann folgende allgemeine Form haben:

function NameDesFilms_DoFSCommand(Name_des_Befehls, Argumente) {
 // Hier folgen dann beliebige Anweisungen
}

Dabei muss der Funktionsbezeichnungsteil vor dem Unterstrich exakt dem Namen des Films, d.h. dem Attribut id im object-Element bzw. dem Attribut name im embed-Element entsprechen. Der Teil des Funktionsnamens nach dem Unterstrich ist ebenfalls exakt so vorgegeben.

Wenn Sie mehrere unterschiedliche Befehle mit FSCommands an die Mutterseite übermitteln wollen, so können Sie dies innerhalb des Funktionskörpers fallunterschieden je nach Name_des_Befehls über if- oder case-Abfragen tun. Die if-Abfrage ist im vorliegenden Beispiel eigentlich nicht erforderlich, da es dort ja nur den einen Befehl "melden" gibt. Sie dient hier aber zur Veranschaulichung des Prinzips.

Der Aufruf der JavaScript-Funktion NameDesFilms_DoFSCommand(Name_des_Befehls, Argumente) erfolgt aus dem Flash-Film heraus über ein ActionScript der allgemeinen Form fscommand("Befehl", Argumente);.

nach obennach unten

Kommunikation zweier Flash-Filme via FSCommand und JavaScript

Da - wie gesehen - JavaScript den Flash-Film steuern und umgekehrt ein ActionScript aus dem Flash-Film heraus auch JavaScript-Funktionen aufrufen kann, können über den Umweg von JavaScript auch zwei getrennte Flash-Filme miteinander kommunizieren. In aller Regel wird man zwar versuchen, eine solche Konstruktion zu vermeiden und stattdessen lieber gleich alles in einen Flash-Film packen. Eine Aufteilung in zwei Flash-Filme, die miteinander interagieren, kann aber z.B. erforderlich werden, wenn man zwei Menü-Steuerungen "über Eck", d.h. z.B. links und oben auf einer HTML-Seite mit Flash realisieren möchte, den Hauptanzeigebereich aber ohne Flash.

Beispiel Einbindung in HTML:

Popup-Seite Anzeigebeispiel: So sieht's aus

<HTML><HEAD><TITLE>LiveConnect</TITLE>
<script type="text/javascript" src="FindeFlash.js"></script>
<SCRIPT type="text/javascript">
<!--
var movie1;
var movie2;

function Zwilling2_DoFSCommand() {
  if (movie1) {
    movie1.LoadMovie(0, "Zwilling.swf");
    movie1.Play();
  }
}

function Zwilling1_DoFSCommand() {
  if (movie2) {
    movie2.LoadMovie(0, "Zwilling.swf");
    movie2.Play();
  }
}

function init () {
  var movie1 = findeFlash('Zwilling1');
  var movie2 = findeFlash('Zwilling2');
  if (movie1)
    movie1.LoadMovie(0, "Zwilling.swf");
    movie1.Play();
  }
}

if (navigator.appName && navigator.appName.indexOf("Microsoft") != -1 &&
        navigator.userAgent.indexOf("Windows") != -1 &&
        navigator.userAgent.indexOf("Windows 3.1") == -1) {
   document.write('<SCRIPT type="text/vbscript"> \n');
   document.write('on error resume next \n');
   document.write('Sub Zwilling1_FSCommand(ByVal command, ByVal args)\n');
   document.write('  call Zwilling1_DoFSCommand(command, args)\n');
   document.write('end sub\n');
   document.write('on error resume next \n');
   document.write('Sub Zwilling2_FSCommand(ByVal command, ByVal args)\n');
   document.write('  call Zwilling2_DoFSCommand(command, args)\n');
   document.write('end sub\n');
   document.write('</SCRIPT\> \n');
}
//-->
</SCRIPT>
</HEAD>
<BODY onLoad="window.setTimeout('init()',3000)" bgcolor="#FFFFFF">

<object id="Zwilling1">
  <param name="movie" VALUE="Container.swf">
 // Einbettung analog zu einer der beiden Varianten aus Beispiel 1
 // mit entsprechenden Benennungen in ID und/oder NAME
 // und Pfaden zur SWF-Datei "Container.swf"
</object>

&nbsp;

<object id="Zwilling2">
  <param name="movie" VALUE="Container.swf">
 // Einbettung analog zu einer der beiden Varianten aus Beispiel 1
 // mit entsprechenden Benennungen in ID und/oder NAME
 // und Pfaden zur SWF-Datei "Container.swf"
</object>


</BODY>
</HTML>

Beispiel Erstellung Flashfilm:

Aktionen für Bild 1 des Ebenennamens skript
_global.beginn = getTimer();
_global.ende = 20 * 1000;
_global.abgel = beginn;
strahl.gotoAndPlay("anfang");
 
 

Aktionen für Bild 2 (Beschriftet lauf) des Ebenennamens skript
abgel= getTimer() - beginn;
ratio = abgel/ende;
if (abgel<ende) {
        setProperty("sickerM",_height,40*(1-ratio));
        setProperty("haufen",_height,100*ratio);
        setProperty("haufen",_width,200*ratio);
        setProperty("haufen",_y,53+(Math.pow(31,(1-ratio))));
        txt.text=Math.ceil((ende-abgel)/1000);
} else {
        txt.text="0";
}
 
 

Aktionen für Bild 3 des Ebenennamens skript
if (abgel<ende) {
          gotoAndPlay("lauf");
  } else {
          stop();
}
 
 

Erläuterung:

Auf der Beispielseite ist, getrennt durch ein nicht-umbrechendes Leerzeichen &nbsp; der "Flashfilm" mit dem Dateinamen Container.swf zweimal nebeneinander eingebunden. Der "Flashfilm" Container.swf hat dieselben Dimensionen (45*90 Pixel) und Hintergrundfarbe wie die bereits bekannten Beispielsanduhren, besteht aber lediglich aus einem einzigen Bild mit einer leeren Ebene 0. In den ersten der beiden "Container" mit der Bezeichnung id="Zwilling1" bzw. name="Zwilling1" wird, nachdem die Seite komplett geladen ist, der Flashfilm Zwilling.swf geladen und gestartet. Dies wird durch den Aufruf der JavaScript-Funktion init() bewirkt. Gleichzeitig werden mit dieser Initialisierungs-Funktion die beiden globalen Variablen movie1 und movie2 einmalig mit Werten belegt, über die die beiden Flash-Filme später auch in den beiden übrigen Funktionen immer wieder differenziert angesprochen werden können.

Mit Rücksicht auf langsame Rechner empfiehlt es sich, die Initialisierungsfunktion init() nicht direkt aufzurufen, sondern mit einer Verzögerung von einigen Sekunden (In obigem Beispiel: 3000 Millisekunden). Bei einigen Browsern kann es ansonsten zu Fehlermeldungen kommen, nämlich dann, wenn der EventHandler onLoad() bereits feuert, obwohl noch nicht alle Kind-Elemente (hier: beide Flash-Container) geladen sind.

Nachdem der Flashfilm Zwilling.swf in den ersten Container geladen ist und dessen Laufzeit von 20 Sekunden verstrichen ist, ruft ein FSCommand aus diesem Film heraus die hierfür zuständige JavaScript-Funktion Zwilling1_DoFSCommand() auf. Diese Funktion lädt und startet dann den gleichen Sanduhren-Film Zwilling.swf auch im zweiten "Container" mit der Bezeichnung (id="Zwilling2" bzw. name="Zwilling2").

Nach Ablauf der Zeit von 20 Sekunden ruft ein FSCommand aus diesem nachträglich in den zweiten Container geladenen Film heraus die hierfür zuständige JavaScript-Funktion Zwilling2_DoFSCommand() auf, die ihrerseits den Film im ersten "Container" wieder neu lädt und startet, usw. usf. ...

Damit die Laufzeit der Sanduhren immer wieder auf 20 Sekunden zurückgestellt wird, muss im ersten Bild des Flash-Films Zwilling.swf, der nur einmal zu Beginn nach einem (Neu-)Aufruf durchlaufen wird, die Startzeit über getTimer() neu gesetzt werden. Die in der globalen Variable beginn gespeicherte Startzeit wird dann im zweiten Bild jeweils von dem in der globalen Variablen abgel gespeicherten Wert der bereits abgelaufenen Zeit subtrahiert, um ihn zu der in der globalen Variablen ende gespeicherten Laufzeit ins Verhältnis setzen zu können.

nach obennach unten

Kommunikation zweier Flash-Filme via getURL-Aufruf von JavaScript

Natürlich kann man zur Kommunikation zweier Flash-Filme auch wieder die Funktion getUrl() zweckentfremden. Ob man dabei wie in dem zuletzt präsentierten Beispiel die Uhren über allgemeine Flash-Methoden (neu)startet, oder wie im folgenden Beispiel über ein komlettes Neuladen eines Frames, in den sie jeweils eingebunden sind, ist Geschmacksache.

Der hier gewählte Ansatz funktioniert mit einem kleinen Trick auch in Opera:

Beispiel Einbindung in HTML:

Popup-Seite Anzeigebeispiel: So sieht's aus

<html><head><title>LiveConnect</title>

<SCRIPT type="text/javascript">
<!--
var dran =.5;

function wechsel () {
  self.frames[dran+.5].location.href="Tante.htm";
  dran*=-1;
}
//-->
</script>

</head>
<frameset frameborder="yes" border="1" framespacing="1"  cols="65,*">
   <frame scrolling="no" src="Tante.htm">
   <frame scrolling="no" src="leer.htm">
</frameset>
</html>

Beispiel Erstellung Flashfilm:

Aktionen für Bild 51 des Ebenennamens maske
getURL("javascript:wechsel()", "_parent");
stop();
 
 

Erläuterung:

Bei der Beispielseite handelt es sich um ein aus zwei Frames bestehendes Frameset. Während in den rechten Frame zunächst nur eine leere Seite geladen wird, wird im linken Frame eine Seite mit dem Dateinamen Tante.htm angezeigt, in die eine Flash-Sanduhr mit dem Dateinamen Cousin.swf mit einer Laufzeit von 20 Sekunden eingebunden ist. (s.u.)

Nach Ablauf der Laufzeit wird über getUrl() die JavaScript-Funktion wechsel() aufgerufen, die im <head>-Bereich des übergeordneten Framesets, also dem _parent von Tante.htm definiert ist.

Die Funktion wechsel() bewirkt dann, dass in den bisher leeren rechten Frame ebenfalls die Datei Tante.htm mit dem dort eingebundenen Flashfilm Cousin.swf geladen wird, nach dessen Ablauf erneut die Funktion wechsel() im übergeordneten Frameset aufgerufen wird.

Über die dort global definierte JavaScript-Variable dran wird geregelt, welcher der beiden Frames jeweils mit dem Neuladen "dran" ist. Die Variable dran speichert eine Zahl mit dem Betrag 0,5. Bei jedem Aufruf der Funktion wechsel() wechselt dran allerdings sein Vorzeichen. Durch Addition des Wertes +0.5 wird die Datei Tante.htm abwechselnd in den rechten Frame self.frame[1] bzw. den linken Frame self.frame[0] neu geladen.

Da wie oben bereits beschrieben, der Browser Opera die Funktion getUrl() nur auf den Frame bzw. das Fenster beziehen kann, in dem der Flash-Film selbst eingebunden ist, ist im vorliegenden Beispiel auch in Tante.htm eine JavaScript-Funktion wechsel() definiert:

Beispiel Einbindung in HTML:

<HTML><HEAD><TITLE>Tante</TITLE>

<SCRIPT type="text/javascript">
<!--
function wechsel () {
  parent.wechsel();
}
//-->
</script>

</HEAD>
<BODY bgcolor="#FFFFFF">

<object id="Cousin">
 // Einbettung analog zu einer der beiden Varianten aus Beispiel 1
 // mit entsprechenden Benennungen in ID und/oder NAME
 // und Pfaden zur SWF-Datei "Cousin.swf"
</object>

</BODY>
</HTML>

Erläuterung:

Die Funktion wechsel() in Tante.htm macht nichts anderes, als die gleichnamige Funktion wechsel() im übergeordneten Frameset aufzurufen. Dies dient wie gesagt nur als Behelfskonstruktion für den Browser Opera, der auch als einziger von der in Tante.htm definierten Funktion Gebrauch macht.

nach obennach unten

Die Schnittstelle JavaScript / Flash

Bei diesem Thema ist jetzt leider Schluss mit lustig; so einfach, wie Macromedia, die Herstellerfirma des Flash-Plugins und des entsprechenden Autorenprogramms es glauben machen will, ist es für JavaScript nämlich häufig nicht, auf das Plugin zuzugreifen.

Das auf der Macromedia-Seite vorgestellte Konstrukt var movie = window.document.movie ermöglicht es JavaScript nämlich in aller Regel nur unter Windows - und das je nach verwendetem Browser auch nur unter bestimmten Windowsversionen, über allgemeine Flash-Methoden wie SetVariable(), LoadMovie() oder Play() etc., den Ablauf eines Flash-Films zu beeinflussen. Ein weiterer Nachteil der Macromedia-Schnittstelle ist, dass eine Fehlerbehandlung noch nicht einmal ansatzweise betrieben werden kann.

Vgl. hierzu:

englischsprachige Seite http://www.macromedia.com/support/flash/publishexport/scriptingwithflash/scriptingwithflash_03.html.

Höhere Erfolgsquoten kann man beim LiveConnect erzielen, wenn man nicht auf die in den obigen Anzeigebeispielen folglich auskommentierte Macromedia-Schnittstelle setzt, sondern zum Erkennen des Plugins eine eigene JavaScript-Funktion benutzt. Eine Fehlerbehandlung kann hier zumindest teilweise betrieben werden. Auch sind in dieser Hinsicht sicher noch Verbesserungen an dem Skript möglich. Dem Anspruch, jeden Fehler abzufangen, der sich bei unterschiedlichen Browser- und Betriebssystem-Konstellationen ergeben könnte, wird man allerdings wohl auch bei diesem Ansatz niemals genügen können.

Die Funktion findeFlash() wurde in zwei Beispielen oben bereits verwendet und war dort über ein externes JavaScript eingebunden:

Beispiel externe JavaScript-Datei "FindeFlash.js":

//Datei FindeFlash.js

  function findeFlash (flash) {
    if (document.all) {
      if (document.all[flash]) {
        return document.all[flash];
      }
      if (window.opera) {
        var movie = eval(window.document + flash);
        if (movie.SetVariable) {
          return movie;
        }
      }
      return;
    }
    if(document.layers) {
      if(document.embeds) {
        var movie = document.embeds[flash];
        if (movie.SetVariable) {
          return movie;
        }
      }
      return;
    }
    if (!document.getElementById) {
      return;
    }
    var movie = document.getElementById(flash);
    if (movie.SetVariable) {
      return movie;
    }
    var movies = movie.getElementsByTagName('embed');
    if (!movies || !movies.length) {
      return;
    }
    movie = movies[0];
    if (movie.SetVariable) {
      return movie;
    }
    return;
  }

Erläuterung:

Die Beispiel-Funktion zur Erkennung des Flashplugins erhält in der Variablen flash die ID des Object-Elements bzw. den NAME des Embed-Elements als Übergabeparameter.

Für den Fall, dass der Browser das All-Objekt versteht, (in Betracht kommen hier vor allem der Microsoft Internet Explorer und Opera), wird zunächst mit if (document.all[flash]) weiter abgefragt, ob er das Plugin mit der übergebenen Kennung damit auch identifizieren kann.

Beim Microsoft Internet Explorer ist dies der Fall. Normalerweise würde man nun, bevor man das entsprechende Objekt als Rückgabewert zurückliefert, auch noch abfragen, ob sich darauf denn nun auch überhaupt die betreffenden allgemeinen Flash-Methoden anwenden lassen, die man zu benutzen gedenkt, so etwas wie if (document.all[flash].SetVariable) also. Beim MSIE führt dies allerdings zu paradoxen Fehlermeldungen des Browsers, der eine solche Methode nicht kennen will, obwohl er sie anstandslos durchführt. Für den Internet-Explorer muss daher - anders als bei den übrigen Browsern - auf diese Abfrage verzichtet werden: Das Flash-Objekt wird ohne Prüfung der Verwendbarkeit allgemeiner Flash-Methoden zurückgegeben.

Der Browser Opera, dessen All-Objekt nur unvollständig implementiert ist, kann das Flash-Objekt nicht über document.all[flash] zurückliefern und auch nicht über die Methoden document.getElementById(flash) oder document.getElementsByTagName('embed') . Allerdings lässt sich in Opera zumindest unter Windows 98 das Objekt nach der Macromedia-Variante var movie = window.document.movie ansprechen. Um diese Möglichkeit nicht ungenutzt zu lassen, gibt die Funktion das Objekt über eval(window.document + flash) zurück. Dabei ist bei Opera sogar auch eine Prüfung auf die Verwendbarkeit allgemeiner Flash-Methoden möglich. Außer Acht bleiben bei diesem Ansatz freilich Opera-Browser, die auf anderen Betriebssystemen laufen, was dort vermutlich zu Fehlern führt.

Sollte es sich um einen Browser handeln, der zwar über das All-Objekt verfügt, das Flash-Plugin damit aber nicht erkennen kann und kein Opera ist, so liefert die Funktion mit einem simplen return; undefined zurück. Da dies einem false oder einer logischen Null entspricht, lassen sich so Zugriffe auf das nicht erkannte Plugin verhindern, die ansonsten zu Fehlermeldungen führen würden.

Wie in den Beispielen zu nach oben JavaScript beeinflusst ActionScript sowie nach oben Kommunikation zweier Flash-Filme via FSCommand und JavaScript zu sehen, geht das dann mit einer einfachen Abfrage:
var movie = findeFlash('meinMovie');
if(movie){tuWasAmMovie();}

Wenn es sich bei dem Browser um einen Netscape der 4er-Versionen handelt, dann und nur dann versteht er das Layer-Objekt und - bekanntermaßen - auch das Embeds-Objekt. Für den Fall, dass die Unterversion Netscape 4.X mit dem Embeds-Objekt auch das Flash-Objekt identifizieren kann, wird dieses - und ansonsten undefined zurückgegeben.

Wenn es sich ferner um einen Browser handelt, der das "Document Object Model" nicht verfolgt, wird an dieser Stelle ebenfalls undefined zurückgegeben.

Andernfalls - unter den restlichen, wichtigen Browsern kommen hier vor allem Mozilla, sowie die neueren Netscape-Browser der Versionen 6 und 7 in Betracht - wird das Flash-Objekt anhand seiner ID zurückgegeben, vorausgesetzt, dass sich auch die allgemeine Flash-Methode SetVariable() darauf anwenden lässt.

Eine Erkennung des Plugins über seine ID ist jedoch bei diesen DOM-Browsern nur möglich, wenn das Plugin mit einer ID versehen ist. Wurde zur Einbettung die herkömmliche, nicht W3C-konforme Netscape-Methode über des Embed-Element gewählt, so verfügt dieses über keine ID, sondern nur über das Attribut NAME.

Da das Embed-Element allesdings bei der herkömmlichen Methode jeweils als Einzel-Kind in einem Object-Eltern-Element eingebettet ist, lässt es sich als solches über die Methode getElementsByTagName('embed') ansprechen, vorausgesetzt, man wendet diese Methode ausschließlich auf das übergeordnete Eltern-Element an, das man zuvor über seine ID als movie identifiziert hat, handelt es sich bei dem zu erkennenden Flash-Film immer um das erste Element "[0]" des Arrays movie.getElementsByTagName('embed'), also auch dann, wenn es, wie im Beispiel unter nach oben Kommunikation zweier Flash-Filme via FSCommand und JavaScript gesehen, mehrere Embed-Elemente im Gesamtdokument gibt.

Wenn das erkannte Kind-Embed-Element auch noch allgemeine Flash-Methoden besitzt, wird es von der Funktion zurückgegeben, während bei allem anderen über das letzte return; dem Aufrufer mitgeteilt wird, dass das gesuchte Flash-Objekt unter diesem Browser anscheinend nicht ansprechbar ist.

nach obennach unten

Browserunterstützung

Folgende Tabelle listet die Unterstützung der Methoden durch unterschiedliche Browser auf, falls das Flash-Plugin über die <embed>-Methode eingebunden wurde:

Methode MSIE ab 5.0
Windows
Neuere Mozilla,
Firefox,
Netscape 7
Windows
Neuere Mozilla,
Firefox,
Netscape 7
Linux
Netscape 4
Windows
Netscape 4
Linux
Opera 7/8
Windows
Opera 7/8
Linux
Konqueror
ja ja ja ja nein nein nein nein
ja ja ja ja ja teilweise teilweise ja
ja ja ja ja nein nein nein nein

Folgende Tabelle listet die Unterstützung der Methoden durch unterschiedliche Browser auf, falls das Flash-Plugin über die W3C-konforme Methode eingebunden wurde:

Methode MSIE ab 5.0
Windows
Neuere Mozilla,
Firefox,
Netscape 7
Windows
Neuere Mozilla,
Firefox,
Netscape 7
Linux
Netscape 4
Windows
Netscape 4
Linux
Opera 7/8
Windows
Opera 7/8
Linux
Konqueror
ja ja ja ja nein manchmal nein nein
ja ja ja ja ja teilweise teilweise ja
ja nein nein ja nein nein nein nein

nach obennach unten

Beispiele downloaden

Wer sich über die Anzeigebeispiele und die Beschreibungen der jeweils unterschiedlichen Code-Teile hinaus für den kompletten Quellcode und die Grafiken der Sanduhr interessiert, kann sich diese unter dem folgenden Link herunterladen.

ZIP-Datei Flash-Quelltext und Grafiken der Sanduhr

Um Speicherplatz zu sparen, handelt es sich bei der .fla-Datei, für deren Anzeige Sie natürlich auch ein Flash-Autorenprogramm benötigen, um eine zusammengefasste Version aller hier präsentierten Beispiele, wobei nur der Quellcode des ersten Beispiels aktiv und der Rest auskommentiert ist.

Der Autor dieses Artikels verzichtet auf die Rechte am Code und den Grafiken und stellt die Datei als Freeware zur Verfügung. Wer es wünscht, darf daran also nach Herzenslust grafisch und programmiertechnisch herumexperimentieren und sich gegebenfalls daraus auch einen Preloader für eigene Flash-Filme basteln.

Teil von SELFHTML aktuell Teil von Artikel Teil von Programmiertechnik

© 2007 bereichsübergreifende Seite Impressum