![]() |
|
||||||||||
|
|||||
|
UFO
Регистрация: Jul 2007
Сообщений: 173
|
В проектах часто необходимо использовать связки JS с FLASH... Раньше использовался getURL, fscommand, сейчас ExternalInterface, но способ использования обычно ограничивался на вызовове разных функций.
Эта система работала хорошо, но приходилось заранее продумывать систему общения, задавать имена функций. Если немного подумать, можно схитрить и использовать всего две функции, одну входящую для JS и одну входящую для Flash, тогда отдавая в функцию два параметра, первый из которых "евент" и второй системный параметр, можно все упростить. Внутри функций можно написать простой парсер на switch и строить схему по входящим евентам. Эта схема не плоха и действует безукоризненно, пока колличество евентов не переваливает за сотню. Во флеше, очень удобна встроенна система евентов, но как было бы удобно если бы эта же система евентов распространилась и на JS. Например, JS говорит - flashMovie.addJSListener ( "click", myJSFunction ); и флешка добавляет слушателя, а при генерации события "click", любые подписанные на событие слушатели в JS получат уведомление. Теперь собственно вопросы: - А как делаете это взаимодействие Вы? - Есть ли какие-то готовые решения? |
|
|||||
|
Регистрация: Apr 2006
Сообщений: 36
|
Сделать то можно все что угодно. Вопрос размеров конечного JS файла. Проще использовать конкретные вызовы чем разрабатывать механизм прозрачного обмена сообщениями, производительный и небольшой по объему.
|
|
|||||
|
UFO
Регистрация: Jul 2007
Сообщений: 173
|
Вобщем вот набросок, рабочий. Если кому надо, юзайте.
package
{
import flash.display.Sprite;
import flash.events.*;
import flash.external.*;
public class JSListener extends Sprite
{
private var externalHandlers = [];
static private var self;
static public function instance ():JSListener
{
if ( !self ) self = new JSListener ();
return self;
}
public function JSListener ():void
{
ExternalInterface.addCallback ( "addJSListener", addJSListener );
}
public function addJSListener ( eventName:String, functionName:Function ):void
{
externalHandlers = {};
if ( !( eventName in externalHandlers ) ) externalHandlers [ eventName ] = [];
externalHandlers [ eventName ].push ( functionName );
}
public function JSEvent ( ev, param1 = null, param2 = null ):void
{
var event:Array = ( ( externalHandlers [ ev.name ] || [] ) as Array ).concat ( ( externalHandlers [ '__all__' ] || [] ) as Array );
var o:Object = joinObjects ( param1, param2 );
for ( var i:uint = 0, len = event.length; i < len; i++ ) ExternalInterface.call ( event [ i ], o );
}
private function joinObjects ( a:Object, b:Object ):Object
{
var c:Object = {};
for ( var i in a ) c [ i ] = a [ i ];
for ( i in b ) c [ i ] = b [ i ];
return c;
}
}
}
Использовать можно например так: Т.е. добавляем ссылку на синглтон в область видимости класса. И генерим события. Единственное что смущает, это то что приходится создавать синглтон и проводить инициализацию. Может можно сделать более красивое решение? Последний раз редактировалось ALiEN_; 21.04.2008 в 15:21. |
|
|||||
|
UFO
Регистрация: Jul 2007
Сообщений: 173
|
Доработал класс. Некоторые возможности:
- прозрачная генерация и получение событий (JS <-> AS, AS <-> AS, JS <-> JS); http://qwehkwerjhbgkwe.livejournal.com/51060.html |
|
|||||
|
Большое спасибо за класс.
ЗЫ, я думаю тему есть смысл переместить в ФАК.
__________________
Тут мужик танцует и поёт про флэш |
|
|||||
|
UFO
Регистрация: Jul 2007
Сообщений: 173
|
Надо чтобы гуру форума заценили для начала ) Класс ведь реально весьма полезный и многим пригодится.
На всякий случай добавлю сюда код, т.к. в жж он побился. Вот некоторые возможности: - прозрачная генерация и получение событий ( JS <-> AS, AS <-> AS, JS <-> JS ); - возможность использовать флешку чисто, как обсервер для JS; - возможность рассылать события бродкастом, т.е. нам все равно где находится подписчик какая у него глубина вложенности и т.д.; - не имеет значения, где находится подписчик во флеш или в JS и не важно кто сгенерит событие. - есть событие __all__, при подписке к которому подписчик будет слышать вообще все евенты. package
{
import flash.external.*;
public class EManager extends Object
{
private var externalHandlers = [];
static private var _inst:EManager;
static public function get inst ()
{
if ( !_inst ) _inst = new EManager ();
return _inst;
}
public function EEventDispatcher ():void
{
ExternalInterface.addCallback ( "subscribe", subscribe );
ExternalInterface.addCallback ( "unsubscribe", unsubscribe );
ExternalInterface.addCallback ( "notify", notify );
}
public function subscribe ( event:String, handler ):void
{
if ( !( event in externalHandlers ) ) externalHandlers [ event ] = [];
externalHandlers [ event ].push ( handler );
}
public function unsubscribe ( event:String, handler ):void
{
var handlers:Array = externalHandlers [ event ];
if ( handlers )
for ( var i:uint = 0, len = handlers.length; i < len; i++ )
if ( handlers [ i ] == handler )
{
handlers.splice ( i, 1 );
break;
}
}
public function notify ( event:String, params:Object = null ):void
{
var handlers:Array = ( ( externalHandlers [ event ] || [] ) as Array ).concat ( ( externalHandlers [ '__all__' ] || [] ) as Array );
for ( var i:uint = 0, len = handlers.length; i < len; i++ )
{
if ( handlers [ i ] instanceof Function )
handlers [ i ] ( params );
else
ExternalInterface.call ( handlers [ i ], params );
}
}
}
}
Например подпишемся на евент прямо во флеше, и получим его: подписка от JS происходит точно так же =) Последний раз редактировалось ALiEN_; 26.04.2008 в 14:31. |
|
|||||
|
стервочка (я мужик)
|
ничё прозрачного я в этом не вижу.
|
|
|||||
|
UFO
Регистрация: Jul 2007
Сообщений: 173
|
а что именно смущает?
|
|
|||||
|
стервочка (я мужик)
|
собственно вся конструкция и смущает.
|
|
|||||
|
UFO
Регистрация: Jul 2007
Сообщений: 173
|
во всяком случае, я еще альтернатив не видел.
|
![]() |
![]() |
Часовой пояс GMT +4, время: 15:23. |
|
|
« Предыдущая тема | Следующая тема » |
|
|