質問: datagridのスクロールについて はじめまして、papillon68と申します。 「flash mx professional 2004」を使っています。 その中のコンポーネント「datagrid」についての質問です。 ◆困っていること datagridで勝手に選択中のアイテムがスクロールする (htmlにobjectタグでswfファイルを読み込んでいます) ◆したいこと datagridで勝手に選択中のアイテムがスクロールしないようにしたい ◆現象 1.グリッド中のアイテムを選択する 2.1でマウスの左クリックを押したままflash(swf) 外にドラッグする 3.再びflash(swf)内にマウスを持っていく 3のとき [マウス] ------- | |↑ |グリッド|↑ | |↑ ------- マウスがグリッドより上(x座標が大きい)に あればグリッド内が勝手に上にスクロール ------- | |↓ |グリッド|↓ | |↓ ------- [マウス] マウスがグリッドより下(x座標が小さい)に あればグリッド内が勝手に下にスクロール 実際にはselectedindexなどは変わっておらず、 見た目の選択中(緑のライン)が移動します。 分かりにくいかもしれませんが、解決策や情報を お持ちでしたらご教授お願いできませんでしょうか。 よろしくお願い致します。
回答: #2です。 > flashエリア外(html部分)までドラッグし、そこでマウスアップし、 > 再びflashエリア内にマウスを持っていくとドラッグをしていないのに > 自動スクロールしてしまう ・・・というのは、datagrid のというより flash player そのものの仕様が原因だと思います。 mousedown と mouseup 、rollover と rollout イベントは対になっています。 例えば mouseup イベントは、mousedown イベントが発生した後でなければ発生しません。 flash がこれらのイベントを検出できるのは、flash ムービーにフォーカスがある間だけです。 例えばあるムービークリップで、普段はフレーム1、mousedown でフレーム2を表示し、mouseup でフレーム1に戻るとします。 flash 内でマウスのボタンを押して離した時は何の問題もないのですが、flash 内でボタンを押して flash の外で離すと、mouseup イベントが検出されないためにフレーム1には戻りません。 再度 flash にフォーカスが戻ってきた時は、前回の mousedown イベントはクリアされてなくなっています。 ですから、一旦 flash 内でクリックして mousedown イベントを発生させてからでないと mouseup イベントは発生しません。 このあたりの事情が原因で” mousedown と、その対になる mouseup ”というサイクルが狂い、その瞬間だけ妙な現象が起きるけれど何回かクリックしているうちにいつの間にか正常に戻っていたり、逆にクリックを繰り返したせいで余計におかしくなることがよくあります。 なお、rollover と rollout でも、同様の理由により同じ現象が起こります。 *************************** list コンポーネントの自動スクロールは、 ・リスト内でボタンが押されたら、dragscroll 関数を setinterval で一定間隔ごとに実行する ・マウスのボタンが離されたら、タイマーを削除して自動スクロールを停止する という仕組みになっているようです。 マウスのボタンが離されたかどうかの判定には mouseup イベントを利用しています。 リスト内で押したボタンを flash の外で離した場合は mouseup イベントが検出されず、従って自動スクロールを実現しているタイマーは削除されません。 そのため、スクロールの関数はボタンを離した後も一定時間ごとに呼び出され続けます。 つまり、自動スクロールのためのタイマーがセットされた後、flash 外でマウスのボタンを離したために mouseup イベントが検出されずタイマーが削除されなかった場合は、リスト内でクリックしていなくても、前回セットされたタイマーに従ってスクロール関数が一定時間ごとに実行されます。 flash 外でボタンを離した後で戻ってくるとドラッグしていないのに勝手にスクロールするのは、このためと考えられます。 flash の領域外はもう別世界ですし、こればかりはスクリプトや何かでどうこうできる問題ではありません。 ましてコンポーネントが相手では、自分なりの工夫を施すことも困難です。 html ページの中では、flash もページを構成する要素の1つに過ぎません。 マウスの入力情報やフォーカスは flash だけが独占して管理できるものではないので、バグともどうにもできない仕様とも言い難い問題です。 あとは、flash 内でクリックして flash 外で離す・・・なんてひねくれたことをする人が少ないことを祈るくらいでしょうか。 グリッドの上下に隙間を設け、flash 外でボタンが離される確率を減らすデザインにするのも1つの手だと思います。 *************************** adobe exchange という、旧 macromedia 製品用のコンポーネント等を配布・販売しているページがあります。 このページでは、品物のリストを datagrid のようなグリッドで表示しています。 こんな現象が起こることを知っていて無用のトラブルやクレームを未然に防ぐためか、exchange のグリッドはドラッグによるスクロールができないように作られています。 ・flash exchange http://www.adobe.com/cfusion/exchange/index.cfm#loc=en_us&view=sn110&viewname=flash%20exchange ↑このグリッドでは行をクリックしても何も起こりません(ハイライトのマーカーもなし)し、クリックしてドラッグアウトしてもスクロールしません。 スクロールはスクロールバーでのみ可能です。 行そのものが選択不可能になっている代わりに項目名が html タグ対応のテキストフィールドになっていて、特定の部分をクリックすると対応するコンテンツや制作者のホームページ等に移動します。 このグリッドは exchange のために作られた特注品であって、flash に付いている datagrid コンポーネントとは全くの別物なのかもしれません。 それはさておき、「つまらないトラブルの原因になりかねない自動スクロール機能は、最初から実装しない」という選択肢もアリということなんでしょうね。 ちょっとずるい対策ですが ^^; ちなみに#2でご紹介した enabled を false にし html 対応のカスタムセルを作るという力技は、この設計をヒントにしたものです。