複数のサブコンポーネントを持つ複合コンポーネントがあります。ユーザーが親コンポーネントをクリックすると、フォーカスが取得されますが、その子の 1 つも取得されます。これは発生することに興味がありません。それを防ぐ方法はありますか、それともフォーカスは常に編集可能な (サブ) コンポーネントに置かれますか? ありがとう。
2 に答える
はい、以下にリストされているプロパティのいくつかの組み合わせを使用する必要があります。Flash API で定義されたプロパティに加えて、Flex は追加のプロパティを追加することに注意してください。
このトピックは私にとって常に少し混乱を招くものであり、通常はさまざまなプロパティを有効/無効にして実験しています。次のようなことをする必要があると思います:
parentComponent.tabChildren = false;
parentComponent.hasFocusableChildren = false;
// the above is probably enough, but you can also do...
childComponent.tabEnabled = false;
childComponent.focusEnabled = false;
childComponent.mouseFocusEnabled = false;
childComponent.tabFocusEnabled = false;
便利なマウス/キーボード フォーカス関連のプロパティのリストを次に示します。
mouseChildren
- オブジェクトの子がマウスまたはユーザー入力デバイスを有効にするかどうかを決定します。mouseEnabled
- このオブジェクトがマウスまたはその他のユーザー入力メッセージを受け取るかどうかを指定します。tabChildren
- オブジェクトの子がタブ対応かどうかを決定します。tabEnabled
- このオブジェクトがタブ オーダー内にあるかどうかを指定します。
以下は Flex でのみ機能します。
focusEnabled
- タブで移動したときにコンポーネントがフォーカスを受け取ることができるかどうかを示します。hasFocusableChildren
- 子オブジェクトがフォーカスを受け取ることができるかどうかを示すフラグ。mouseFocusEnabled
- クリックしたときにフォーカスを受け取ることができるかどうか。tabFocusEnabled
- このオブジェクトが TAB キーを介してフォーカスを受け取ることができるかどうかを示すフラグ これは、Flash Player で使用される tabEnabled プロパティに似ています。これは通常、キーボード入力を処理するコンポーネントに当てはまりますが、コントロールバーの一部のコンポーネントでは、エディターなどの別のコンポーネントからフォーカスを盗むべきではないため、false に設定されています。
AS3 でこれを処理する適切な方法は、InteractiveObject の tabEnabled プロパティを使用することです。FLEXを忘れてください。
tabEnabled プロパティは、マウスでクリックしたときに InteractiveObject がフォーカスを受け取り、mouseFocusChanged イベントを生成するかどうかを制御します。
私は非常に精巧なフォーカス変更メカニズムと追跡を実装しました。私の経験から、何かがマウスまたはタブ キーを介してフォーカスを受け取ることができるかどうかを制御するためにのみ、tabEnabled を使用するのが最善です。
まず、入力タイプの TextField、SimpleButton、および buttonMode = true の Sprites/MovieClip では、デフォルトで tabEnabled が true になります。したがって、このデフォルトに遭遇します。いつどこでオーバーライドするかを覚えておくよりも、それを尊重する方が簡単です。
第 2 に、クリックしたときにフォーカスを受け取るカスタム オブジェクトの場合、tabEnabled は基本的に組み込みプロパティであり、タブ キーとマウス クリックの両方でオブジェクトにフォーカスを割り当てるかどうかを制御します。tabEnabled は実際には「canReceiveFocusViaKeyboardOrMouse」のように機能するため、ひどい名前です。これは、任意の InteractiveObject インスタンスを stage.focus に割り当てることができるためです。デフォルトの動作をオーバーライドする以外に、InteractiveObject にフォーカスが割り当てられないようにする方法はないため、tabEnabled を操作する必要があります。
これで、key_focus_change および mouse_focus_change イベントをインターセプトすることで、デフォルトの動作を簡単にオーバーライドできます。
Mouse_focus_change は、現在フォーカスがあるオブジェクトにのみディスパッチされます。技術的には、何もフォーカスがないときにステージにフォーカスがあるため、最初に何かをクリックすると、ステージをターゲットとしてイベントが生成されます。同様に、ステージをクリックすると、フォーカスは null に設定されますが、技術的にはステージはフォーカスを取り戻しています。
Key_focus_change は同様に機能しますが、ステージにフォーカスがある場合にタブを押しても、Flash Player 内のオブジェクトに移動しません。フォーカスが変更されないか、他の HTML コントロールがフォーカスを取得します。それは設計によるものです。一方、プレーヤー内のオブジェクトにフォーカスがある場合、タブを押すと、ステージに戻ることなく、使用可能なタブが有効なオブジェクトをループします。それも設計によるものです。たとえば、ステージ上に tabEnabled オブジェクトが 1 つしかなく、そのオブジェクトにフォーカスがある場合、タブを押してもフォーカスが離れることはありません。実際には、フォーカスをそれ自体にループバックし、その focusRect をアクティブにします (変更のソースがキーの押下であるため)。個々のオブジェクトまたはステージ上でグローバルに、キー変更でアクティブ化されたフォーカス矩形をオフにすることができます。
今楽しい部分。特定の状況下で key_focus_change のデフォルトを実際にインターセプトして防止し、タブキー用に独自の key_down ハンドラーを実装することをお勧めします。たとえば、コントロールの独自のサブセットがフォーカスを受け取るようにする場合は、key_focus_change イベントをインターセプトし、フォーカスを持つオブジェクトが定義済みオブジェクトの 1 つであるかどうかを確認します。そうである場合は、デフォルトを防止し、Tab キーを押すハンドラーがフォーカスをループ内の次の項目に移動できるようにします。この手法を使用して、ループ内のオブジェクトが見つかるまで親チェーンをたどり、そのオブジェクトがフォーカスを失っていると想定して、定義済みのフォーカス ループ内の次のアイテムにフォーカスを移動することもできます。本質的には、フォーカス可能なコントロールのサブセットにのみ焦点を合わせて、タブ キーの粒度を細かくする機能があります。
サイドノート
mouseChildren を false に設定すると、子がマウス イベントのターゲットにならないだけなので、親のヒット エリアには引き続き影響します。親が mouseEnabled = false の場合、マウス イベントを受信しません (ただし、子自体として、親のヒット領域として機能することはできます)。mouseEnable = false および mouseChildren = false に設定すると、mouseEnabled = false に設定し、すべての子の mouseEnabled プロパティを false に設定するのと同じになります。つまり、mouseChildren = false の設定は、すべての子オブジェクトの mouseEnabled プロパティを個別に false に設定する代わりのショートカットにすぎません。