一度のmousemoveイベントで、h5trackmoveが2回動作する。endについても同様。 #150

Closed
fukudayasuo opened this Issue Jan 17, 2013 · 3 comments

Comments

Projects
None yet
2 participants
@fukudayasuo

#137  の対応で、move,endイベントをdocumentだけでなく、ルートエレメントにもバインドするようにしました。

そのため、move/end実行時に2度ハンドラが実行されています。

move,endをトリガで実行した場合は、documentとルートエレメントのハンドラに渡されるjQueryイヴェントオブジェクトが同一インスタンスであるため、h5CustomEventTriggeredのフラグを見て2重にトリガされることはありません。
(そのためテストでこの問題を発見できていませんでした)。

しかし、実際のmousemoveで実行されるハンドラに渡されるjQueryイベントオブジェクトはdocumentとルートエレメントでインスタンスが異なるため、フラグを見れずに、h5trackイベントを2回トリガしてしまいます。

originalEventにフラグを建てれば回避できると思われます。

mousemoveのdispatchEvent(IE8-の場合はfireEvent)でこの問題を確認できるため、テストケースを追加します。

fukudayasuo pushed a commit to hifive-labs/hifivemain that referenced this issue Jan 17, 2013

fukudayasuo pushed a commit to hifive-labs/hifivemain that referenced this issue Jan 18, 2013

fukudayasuo pushed a commit to hifive-labs/hifivemain that referenced this issue Jan 18, 2013

fukudayasuo
#150 テストケース追加しました
dispatchEventでh5trackをテストするケースについて、
ルートエレメント内の要素にh5track*をバインドするケースを追加しました。
@fukudayasuo

This comment has been minimized.

Show comment
Hide comment
@fukudayasuo

fukudayasuo Jan 18, 2013

dispatchEvent(fireEvent)を使ってh5track*をテストするケースを追加しました。

jQueryイベントオブジェクトのインスタンスは、親子なら別インスタンス、同一要素なら同一インスタンスになります。

$('#child').bind()
$('#child').bind()
   // -> 同じイベントオブジェクトがハンドラに来る

$('#child').bind()
$('#parent').bind()
  // -> イベントオブジェクトのインスタンスは変わる

しかし、jQueryのtriggerでイベントを発火させた場合は親子でも同一インスタンスになります。

そのためtriggerではこの問題は検知できていませんでした。

dispatchEvent(fireEvent)を使った場合は、実際の操作同様に親子の時にイベントオブジェクトが別インスタンスになるので、dispatchEvent(fireEvent)を使ってh5track*をテストするケースを追加しました。

マウスイベントの場合は、documentとルートエレメントにバインドしていたためにこの問題が発生していましたが、タッチイベントの場合は、documentではなくtouchstartのターゲット要素と、ルートエレメントにバインドしています。
その場合、touchstartをdispatchする要素とルートエレメントが同じ場合、move,endが同じ要素に2回バインドされることになるので、イベントオブジェクトは同一インスタンスになり、この問題は発生しません。

そのため、dispatchする要素がルートエレメントである場合のテストケース(現時点でマウスだけ失敗)と、dispatchする要素がルートエレメントの子要素(現時点でマウスもタッチも失敗)について、イベントの発火回数を確認するケースと、dx,dyが計算されて格納されていることを確認するケースを追加しました。

dispatchEvent(fireEvent)を使ってh5track*をテストするケースを追加しました。

jQueryイベントオブジェクトのインスタンスは、親子なら別インスタンス、同一要素なら同一インスタンスになります。

$('#child').bind()
$('#child').bind()
   // -> 同じイベントオブジェクトがハンドラに来る

$('#child').bind()
$('#parent').bind()
  // -> イベントオブジェクトのインスタンスは変わる

しかし、jQueryのtriggerでイベントを発火させた場合は親子でも同一インスタンスになります。

そのためtriggerではこの問題は検知できていませんでした。

dispatchEvent(fireEvent)を使った場合は、実際の操作同様に親子の時にイベントオブジェクトが別インスタンスになるので、dispatchEvent(fireEvent)を使ってh5track*をテストするケースを追加しました。

マウスイベントの場合は、documentとルートエレメントにバインドしていたためにこの問題が発生していましたが、タッチイベントの場合は、documentではなくtouchstartのターゲット要素と、ルートエレメントにバインドしています。
その場合、touchstartをdispatchする要素とルートエレメントが同じ場合、move,endが同じ要素に2回バインドされることになるので、イベントオブジェクトは同一インスタンスになり、この問題は発生しません。

そのため、dispatchする要素がルートエレメントである場合のテストケース(現時点でマウスだけ失敗)と、dispatchする要素がルートエレメントの子要素(現時点でマウスもタッチも失敗)について、イベントの発火回数を確認するケースと、dx,dyが計算されて格納されていることを確認するケースを追加しました。

@fukudayasuo

This comment has been minimized.

Show comment
Hide comment
@fukudayasuo

fukudayasuo Jan 18, 2013

originalEventを改変してフラグを建てて管理するのではなく、
storedOriginalEvents(配列)をグローバル(Controller.jsのValiables)に置いてフラグ管理するようにする。
storedOriginalEventsはh5trackstart時に初期化し、mousemove,mouseupのoriginalEventを保持する。
その配列のindexをキーに、h5track*をトリガしたかどうかのリストを持つようにする。

move,end(h5trackmove/end?)がdocumentまでバブリングしたときに、そのoriginalEventをstoredOriginalEventsから外す。
documentまでバブリングしなかった時はstoredOriginalEventsにイベントが残るが、endの時にstoredOriginalEventsをリセットする。

という方法で実装します。

originalEventを改変してフラグを建てて管理するのではなく、
storedOriginalEvents(配列)をグローバル(Controller.jsのValiables)に置いてフラグ管理するようにする。
storedOriginalEventsはh5trackstart時に初期化し、mousemove,mouseupのoriginalEventを保持する。
その配列のindexをキーに、h5track*をトリガしたかどうかのリストを持つようにする。

move,end(h5trackmove/end?)がdocumentまでバブリングしたときに、そのoriginalEventをstoredOriginalEventsから外す。
documentまでバブリングしなかった時はstoredOriginalEventsにイベントが残るが、endの時にstoredOriginalEventsをリセットする。

という方法で実装します。

fukudayasuo pushed a commit to hifive-labs/hifivemain that referenced this issue Jan 21, 2013

@fukudayasuo

This comment has been minimized.

Show comment
Hide comment
@fukudayasuo

fukudayasuo Jan 21, 2013

その配列のindexをキーに、h5track*をトリガしたかどうかのリストを持つようにする。

リストではなく、マウス/タッチイベントについてそれに対応するh5track*イベントをトリガしたかどうかをboolean値を持たせるようにしました。

以前はEventオブジェクトにぶら下げて「発火したかどうか」を汎用な仕組みにするため配列で管理していましたが、
イベントにぶら下げるのではなく、ここでしか使わないフラグにしたためです。

その配列のindexをキーに、h5track*をトリガしたかどうかのリストを持つようにする。

リストではなく、マウス/タッチイベントについてそれに対応するh5track*イベントをトリガしたかどうかをboolean値を持たせるようにしました。

以前はEventオブジェクトにぶら下げて「発火したかどうか」を汎用な仕組みにするため配列で管理していましたが、
イベントにぶら下げるのではなく、ここでしか使わないフラグにしたためです。

fukudayasuo pushed a commit to hifive-labs/hifivemain that referenced this issue Jan 21, 2013

fukudayasuo
#150 タッチイベントのある場合は、ルートエレメントにはバインドしないよう修正。
タッチはtouchstartした要素がtargetになるため、2重にh5trackmove/endをバインドする必要がないため。

@ghost ghost assigned fukudayasuo Jan 21, 2013

fukudayasuo pushed a commit to hifive-labs/hifivemain that referenced this issue Jan 28, 2013

fukudayasuo
#150 テストコードをリファクタしました
eventDispatch -> dispatchTrackSrcNativeEvent
 ・mouse/touch毎に関数を作成。
 ・eventNameで振り分けて、mouse/touch用の関数を呼び出す。

@simdy simdy closed this Jan 28, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment