| |||||||
Du magst keine Werbung? Wir auch nicht!
Einfach registrieren und die Werbung ist weg. Diese Nachricht sehen nur nicht registrierte Nutzer.
![]() |
| | LinkBack | Themen-Optionen | Ansicht |
| | #1 (permalink) |
| helpQLODhelp Registriert seit: Feb 2002 Ort: Köln
Beiträge: 8.505
| Event Bubbling in AS2
In Flex (und auch in Javascript) gibt es eine schönes Feature, das sich Event Bubbling nennt. Bubbling bedeutet, dass ein Event, nachdem es vom Empfänger verarbeitet worden ist, an seine Eltern weitergereicht wird. Die Events steigen also wie Luftblasen im Wasser nach oben. In Flash haben wir so eine Hierarchie schon in die MovieClip Klasse eingebaut. Jeder MovieClip ist Kind eines anderen MovieClips. Der oberste MovieClip ist der Clip, auf den _root zeigt. Jeder MovieClip hat eine Eigenschaft _parent, die auf seinen Eltern-MovieClip zeigt. Indem wir dieser Eigenschaft folgen, können wir uns von jedem MovieClip bis zum root hochhangeln. Der root ist der oberste Clip und deshalb ist seine parent Eigenschaft null. Daran können wir erkennen, dass wir oben angekommen sind. ActionScript:
Befinden wir uns z.B. gerade im MovieClip mit dem Pfad _level0.a.b.c, dann gibt das obige Script folgendes aus: _level0.a.b.c _level0.a.b _level0.a _level0 Wir durchlaufen also jeden Clip, bis wir ganz oben angekommen sind. Den gleichen Weg nehmen beim Bubbling die Events. Wenn z.B. der MovieClip c ein release-Event erzeugt, dann bekommt erst c selbst das Event, dann b, dann a und zum Schluss _level0. Das schöne daran ist jetzt, dass a nicht genau wissen muss, woher das Event kommt, also wo c genau in der Hierarchie liegt. Wenn er das Event empfangen will, muss er nichts weiter tun, als zu warten bis es bei ihm ankommt. Ohne Bubbling müsste er sich irgendwie direkt als Listener bei c anmelden, er müsste als den Pfad zu c kennen oder irgendeinen speziellen Mechanismus bereitstellen, wie z.B. dass c sich bei ihm anmeldet. Wenn man c in der Hierarchie verschiebt, muss man diesen Code dann entsprechend anpassen. Mit Bubbling ist es total egal wo c liegt, solange es unterhalb von a ist. Das Event kommt auf jeden Fall bei a an. Jetzt gibt es ja schon diverse Event-Mechanismen wie z.B. den EventDispatcher von Macromedia oder den erweiteren GDispatcher, der z.B. in Alex Uhlmanns AnimationPackage benutzt wird. Es wäre schön, wenn wir den Dispatcher beibehalten könnten, und unser Bubbling einfach hinzufügen könnten. Genau das macht die folgende Klasse: ActionScript:
Die Klasse hat drei statische Methoden, wovon eine nur für den internen Gebrauch gedacht und deshalb private ist. Die Methode initializeBubbling schnappt sich den übergebenen Dispatcher, und überschreibt seine dispatchEvent Methode, so dass sie zusätzlich das Event zu den Eltern verschickt. Die Methode dispatchEvent ermöglicht es ein Event zu verschicken, auch wenn man selbst gar kein Eventdispatcher ist. Die Methode findParentDispatcher liefert den nächsten Dispatcher in der Elternhierarchie.
__________________ Ralf Bokelberg™ - Flex & Flash Consulting Geändert von bokel (14-01-2006 um 00:40 Uhr) |
| | |
| | #2 (permalink) |
| helpQLODhelp Registriert seit: Feb 2002 Ort: Köln
Beiträge: 8.505
|
Schön und gut, aber was kann ich damit anfangen? Hier sind ein paar Beispiele. Das erste Beispiel benutzt die dispatchEvent Methode, um Events von einem normalen Button ausgehend zu dispatchen. ActionScript:
Wie man sieht, ohne dass ich btn direkt anspreche, kann ich ein Event von ihm empfangen. Das geht auch über beliebig viele MovieClip-Ebenen hinweg. Das nächste Beispiel zeigt Bubbling im zusammenhang mit dem Laden von MovieClips. Wie wir alle wissen, kann man einem MovieClip keine Events zuordnen, bevor er geladen ist, weil die Events beim Laden gelöscht werden. Aus diesem Grund kann man z.B. kein onLoad Event von einem geladenen MovieClip bekommen. Mit Bubbling ist das jedoch überhaupt kein Problem. Wir melden einfach den Parentknoten des geladenen Films als Listener an und warten, bis das Event bei ihm ankommt. ActionScript:
Wie man sieht, bekommen wir wunderbare load Events ohne Polling oder MovieClipLoader. Das nächste Beispiel zeigt, wie man eine V2 Komponente dazu bringt, zu bubblen. ActionScript:
In der Bibliothek muss eine V2 Buttonkomponente liegen, damit das funktioniert. Nachdem wir die Buttons in createChildren erzeugt haben, werden sie in initEvent mit der Methode initializeBubbling so initialisiert, dass sie ihre Events bubblen. Deshalb kommen die Events jetzt nicht nur an, wenn wir uns direkt beim button anmelden, sondern auch, wenn wir uns quasi bei uns selbst anmelden. Das ist doch echt schick, oder? Ok, das wars für heute erstmal. Ich bin mir sicher, ihr werdet noch eine Menge interessante Anwendungen dafür finden. Nachdem ich selbst erst etwas skeptisch war, bin ich jetzt überzeugter Bubbler und möchte nicht mehr ohne. Weitere Details und vielleicht Anregungen für Erweiterungen könnt ihr auch der Flexdoku entnehmen. Drei Sachen, die ich zum Beispiel aus der Doku übernommen habe, sind Event.bubbles, Event.currentTarget, und Event.eventPhase. Mit bubbles=false kann man das Bubblen stoppen. Event.currentTarget zeigt immer auf den Dispatcher, der das Event gerade hat. Und eventPhase zeigt an, in welcher der drei Lebensphasen eines Events wir uns befinden. In unserem Fall gibt es allerdings nur die Phasen target und bubbling. Die dritte Phase capture ist quasi das Gegenstück zu bubbling, das Event fliesst von den Elten zu den Kindern. Das habe ich aber nicht implementiert. In Flex lässt es sich auch nur indirekt ansprechen. Eigene Events sind nach meinen Tests nie in der Capturephase. Edit: da haben sich so merkwürdige zeichen eingeschlichen, & #91;steht für eckige Klammer auf. Anscheinend kann der Formatierer damit nicht richtig umgehen. Viel Spaß, Ralf.
__________________ Ralf Bokelberg™ - Flex & Flash Consulting Geändert von bokel (14-01-2006 um 00:43 Uhr) |
| | |
| | #4 (permalink) |
| helpQLODhelp Registriert seit: Feb 2002 Ort: Köln
Beiträge: 8.505
|
LOL, danke schön. Ich hoffe, du kannst was damit anfangen. mfg. r
__________________ Ralf Bokelberg™ - Flex & Flash Consulting |
| | |
| | #6 (permalink) |
| helpQLODhelp Registriert seit: Feb 2002 Ort: Köln
Beiträge: 8.505
|
Das Bubblen hangelt sich am _parent nach oben. Wenn deine Objekte auch eine _parent Eigenschaft haben, dann klappt es. mfg. r
__________________ Ralf Bokelberg™ - Flex & Flash Consulting |
| | |
| | #7 (permalink) |
| Gast
Beiträge: n/a
|
das ist ja wirklich todschick ![]() Im Grunde genommen habe ich also damit die Möglichkeit ein Objekt für einen Event anzumelden, ohne den Dispatcher zu kennen - solange der "unterhalb" von meinem Objekt liegt. Weil ich mein Objekt ja im Prinzip nur bei irgendeinem Glied der Kette für diesen Event anmelden muss. Das gleiche könnte man doch auch erreichen, wenn man einen globalen Dispatcher anlegt und von überall aus dort dispatchEvent() aufruft. Dann hat man auch nicht das _parent-Problem und erreicht auch Listener, die nicht in der Kette liegen. Schönheitsfehler wäre dann natürlich, dass alle Objekte diesen globalen Dispatcher kennen müssten... |
|
| | #8 (permalink) |
| helpQLODhelp Registriert seit: Feb 2002 Ort: Köln
Beiträge: 8.505
|
Ja, das wäre ein Schönheitsfehler, wobei ich damit noch leben könnte, wenn es in der initialize Methode versteckt wäre. Das Problem ist aber, dass es dann z.B. nur einen click-EventDispatcher gibt, d.h. alle Listener müssten alle click Events handeln. Was dann auch wegfällt, ist die Möglichkeit Events auf ihrem Weg nach oben mit weiteren Informationen anzureichern, oder zu filtern oder durch andere Events zu ersetzen, oder ... man würde also eine Menge Möglichkeiten verschenken. mfg. r
__________________ Ralf Bokelberg™ - Flex & Flash Consulting |
| | |
| | #9 (permalink) |
| Gast
Beiträge: n/a
|
stimmt, für click-Events ist das Bubbling optimal. Oder wenn ein Textfeld im Sub-MC Tastaturfocus bekommt und man das "ganz oben" wissen will! Hätte ich schon mal gut brauchen können ![]() Ich hatte auch einen speziellen anderen Anwendungsfall im Kopf: Einen Loader, der für alle MovieClip.loadMovie() oder XML.load() Aktionen einen hübschen Ladebalken einblendet, egal wo gerade etwas reingeladen wird. Wenn irgendwo im Projekt ein Ladevorgang gestartet wird, wird über den globalen Dispatcher ein Event losgeschickt, für den der Loader sich registriert hat. Dann weiß der Loader über die e.target-property wo gerade geladen wird und kann den Fotschritt anzeigen. Beim Bubbling würde der Loader nicht alle Events bekommen (nur von eigenen Sub-MCs). Egal, das ist wohl eher ein anderes Problem |
|
| | #10 (permalink) |
| Crème brûlée Registriert seit: Jan 2006 Ort: Düsseldorf
Beiträge: 719
|
Hallo zusammen, wie müsste ich das denn anstellen, ein Eventbubbling bei verschachtelten Movieclips hinzukriegen, die auf onKeyDown-Ereignisse hören? addEventListener funktioniert ja nicht bei MovieClips - oder bin ich da einfach zu blöd? Viele Grüße, Benjamin |
| | |
| | #11 (permalink) |
| Nagelneuer User Registriert seit: Dec 2005
Beiträge: 924
|
Deine MovieClips müssten eine Klasse haben, die das Eventhandling und Bubbling ermöglicht.
__________________ The fact that you've got "Replica" written on the side of your gun and the fact that I've got "Desert Eagle written on the side of mine ... :D |
| | |
| | #14 (permalink) |
| Crème brûlée Registriert seit: Jan 2006 Ort: Düsseldorf
Beiträge: 719
|
Konkret gehts darum, eine Oberfläche in Flash zu bauen, die ausschließlich mit der Tastatur gesteuert wird. Dabei werden verschiedene Module in die Applikation geladen (die liegen alle untereinander), die jeweils wieder aus Elementen bestehen (Buttons, Textfelder etc.). Nun geht es darum, das Focusmanagement zu planen, d.h. z.B. - Nutzer befindet sich in Modul 1 und kann mit den Tasten links und rechts horizontal im Modul von Button zu Button springen. - nun drückt er den Pfeil nach unten - dieses Event soll vom Modul nicht gehandelt werden, sondern an die übergeordnete Ebene weitergebubbelt werden, damit die dann den Modulfokus wechseln kann - nun hat das Modul 2 den Focus und darin das Element 1 Das ist nur ein einfaches Beispiel. Es kann natürlich vorkommen, dass Elemente auch nur unter bestimmten Umständen Ereignisse verarbeiten sollen. Momentan löse ich das mit Listenern, die bei Bedarf ein- und ausgeschaltet werden - das ist aber nicht sehr elegant und wenig flexibel. Daher wollte ich das gerne mit Bubbling lösen. |
| | |
| | #15 (permalink) |
| Nagelneuer User Registriert seit: Dec 2005
Beiträge: 924
|
Also möchtest du ein Event aus einem geladenen SWF an den übergeordneten SWF schicken?
__________________ The fact that you've got "Replica" written on the side of your gun and the fact that I've got "Desert Eagle written on the side of mine ... :D |
| | |
![]() |
| Lesezeichen |
| Themen-Optionen | |
| Ansicht | |
| |