Записки о Flash

Захват колеса мыши

После перехода на ActionScript 3 и Flash Player 9 вы наверняка сталкивались с тем, что размещенный на странице ролик не захватывает скролл мыши (как это было в ActionScript 1/2), позволяя пользователю прокручивать содержимое страницы независимо от того, находится ли ролик в фокусе или нет. Достаточно давно я опубликовал класс GlobalMouse, он решал данную проблему, но в целом был неудобен именно для решения подобной проблемы. В связи с этим, я написал класс MouseWheel, позволяющий захватывать и отпускать скролл мыши в любой момент времени при необходимости. К сожалению, браузер Safari, а также Mac OS-версии популярных браузеров (Opera/Firefox) не позволяют захватывать скролл мыши, поэтому данный класс в них работать не будет.

Посмотреть демо вы можете здесь. Исходный код примера и сам класс найдете на той же странице.


28 comments

28 Comments so far

  1. murejib January 17th, 2009 11:03

    А проблема скролла на маке решена весьма элегантным костылем для swfobject
    http://blog.pixelbreaker.com/flash/swfmacmousewheel/

  2. etc January 17th, 2009 11:15

    Да, я знаю про это, но MouseWheel не для этого :)
    Он не решает проблемы со скроллингом внутри приложения, он решает проблему монопольного захвата флешем колеса мыши. Под виндой очень актуально.

  3. DataGreed January 18th, 2009 00:34

    А чем таким прикольным Вы генерите страницу с исходным кодом?

  4. etc January 18th, 2009 00:39

    Flex Builder 3, собственно :)

  5. DataGreed January 23rd, 2009 00:48

    Хех, нужно попробовать :)

  6. DataGreed January 23rd, 2009 00:49

    Ради интереса: Вы писали это в FDT?

  7. etc January 23rd, 2009 08:42

    Нет, всё в том же Flex Builder.

  8. neelts January 24th, 2009 10:26

    В опере почему-то со второго раза только захватывает.

  9. etc January 24th, 2009 14:10

    Странно, у меня вроде с первого. Как вариант, первый клик в Опере может быть необработан, т. к. в ней тоже требуется активация swf-ролика, как в IE.

  10. Nasr March 17th, 2009 04:03

    FontLoader ne rabotaet v Adobe AIR.

    Nado dobavit etoto code chtpbi on rabotal:
    var ldrC : LoaderContext = new LoaderContext();
    ldrC.allowLoadBytesCodeExecution = true;
    this._libLoader.loadBytes(fontSWF,ldrC);

  11. s8000_1 March 23rd, 2009 15:22

    У меня тоже не с первого клика срабатывает (в примере скрипта и у себя).

    Работать начинает только после такого:

    MouseWheel.capture();
    stage.addEventListener(MouseEvent.MOUSE_DOWN, this._captureMouse);

    private function _captureMouse(e:Event):void{
    MouseWheel.release();
    MouseWheel.capture();
    }

    Браузер FF3

  12. etc March 23rd, 2009 20:03

    Это странно, должно, по идее, работать с первого раза.

  13. [...] MouseWheel, теперь захват мыши работает сразу и без вопросов. [...]

  14. [...] UPDATE: Причесанный класс только для захвата мыши. [...]

  15. FSB June 10th, 2009 13:04

    Я таким образом реализовывал шорткаты с контролом (ctrl+c и т.п.) – загрузкой avm1 swf и общением через LC.

    Как раз тогда спрашивал как зашить в бинарник swf переменную, для задания id LC в avm1 свэфке )

  16. etc June 10th, 2009 20:48

    Ну вот, наглядный пример теперь есть :)

  17. shaman4d September 19th, 2009 21:10

    Интересный код, работает. Вы могли бы объяснить (даже в отдельном посте) – как устроен ваш класс MouseWheel ?

  18. etc September 20th, 2009 00:58

    Да всё очень просто, в AS1/AS2 подписка на мышь (на то же событие onMouseWheel) приводила к тому, что фокус наглухо захватывался флешкой. В AS3 же захватить скролл мыши невозможно.
    MouseWheel содержит в себе бинарник AVM1-swf-ки, загружает его лоадером, предварительно вписав случайное имя LocalConnection-соединения, которое нужно для того, чтобы можно было отписываться и подписываться на события мыши в AVM1. Т. е. получается валидный swf с нужным именем соединения и кодом, который выполняет простейшие операции по подписке и отписки от событий мыши.

  19. DataGreed September 29th, 2009 17:42

    А под макосью не получиться заставить работать? :)

  20. etc September 29th, 2009 23:00

    Чисто теоретически, но тогда нужно будет интегрировать какой-нибудь JavaScript в это дело.

  21. Beginner October 3rd, 2009 04:32

    Здравствуйте, подскажите, пожалуйста, при подключении класса появляется ошибка

    TypeError: Error #1006: loadBytes не является функцией.

    с чем это может быть связано?

  22. etc October 3rd, 2009 18:03

    Версия плеера должна быть 9.0.45.0 и выше.

  23. Стас October 8th, 2009 20:07

    Спасибо огромное за класс!!!

  24. Фёдор October 8th, 2009 21:59

    Спасибо за класс! Но после захвата мыши не работает прокрутка вниз в mx:List. При том вверх работает.

  25. etc October 8th, 2009 22:05

    Честно говоря, не знаю, каким образом MouseWheel может повлиять на mx:List :)

  26. Beginner October 9th, 2009 15:50

    Все-таки не могу подключить класс нормально, может неправильно что-то делаю.

    Просто написал MouseWheel.capture();

    и выскакивает ошибка

    TypeError: Error #1006: loadBytes не является функцией.
    at ru.etcs.ui::MouseWheel$/capture()
    at classes::Main()

    Пользуюсь flash плеер 10, as3.

  27. etc October 9th, 2009 17:02

    Метода loadBytes не существовало в версиях ниже 9.0.45.0. В десятой он стопроцентно есть. Других вариантов, кроме версии плеера, при которых может возникнуть подобная ошибка, нет.

  28. Beginner October 9th, 2009 19:30

    Разобрался с проблемой. В моем проекте нашелся класс Loader, убрал его, теперь все отлично работает.

    Спасибо большое за такой полезный класс!

Leave a reply