Flex3.5では、stageにリスナ登録したmouseUpイベントハンドラが二重に動作することがある
またFlex3.2とFlex3.5の違いを発見したのでメモ。
事象
stage.addEventListener(MouseEvent.MOUSE_UP, stage_mouseUpHandler); という形で application領域外で起こったmouseUpイベントを拾う実装をしていた。
Flex3.2 では問題なかった。しかし Flex3.5 になると、mouseUpイベントがapplication領域外で起こった場合、stage_mouseUpHandlerが2度呼ばれるという問題が発生した。この問題は、mouseUpイベントの前にデータグリッドを操作(マウス押下による行選択などを)したときのみ発生する。
実装イメージ
public function init():void { // ... obj.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler); stage.addEventListener(MouseEvent.MOUSE_UP, stage_mouseUpHandler); } public function mouseDownHandler(event:MouseEvent):void { // ... obj.startDrag(); } public function stage_mouseUpHandler(event:MouseEvent):void { trace("event.target: " + event.target); obj.stopDrag(); // ... }
原因は分かっていないが、event.targetを調査したところ以下のことが分かった。
■データグリッド操作をしていない場合
event.target: stage
■データグリッド操作をした場合
event.target: mouseCatcher event.target: stage
…mouseCatcherってなにもの?とデバッグしたところ、systemManager.mouseCatcherがstageのイベントハンドラを動かしていることを確認。枠外のmouseUpイベントを二重で拾ってしまっている模様。
更にmouseCatcherについて調べたところ、ネット上では以下の記述しか見つからず。データグリッド操作との関連は結局分からなかった。
mouseCatcher は application 領域外の MOUSE_UP イベントを拾うためのもののようなので、...
http://www.fxug.net/modules/xhnewbb/viewtopic.php?topic_id=1816&forum=16&post_id=7565
対処
原因が分からずすっきりしないところですが…、mouseCatcherからの呼び出しが余分である以上、抑止すれば直ります。。
対処イメージ
public function stage_mouseUpHandler(event:MouseEvent):void { if (event.target.name == 'mouseCatcher') { return; } obj.stopDrag(); // ... }