2

我有一个包含几个子组件的复合组件。当用户单击父组件时,它会收到焦点,但随后它的一个子组件也会获得焦点,我对此不感兴趣。有什么方法可以防止这种情况发生,或者焦点是否一定总是在可编辑(子)组件上?谢谢。

4

2 回答 2

1

是的,您需要使用下面列出的属性的某种组合。请注意,除了 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- 指定此对象是否按 Tab 键顺序。

以下仅适用于 Flex:

  • focusEnabled- 指示组件在选项卡到时是否可以接收焦点。
  • hasFocusableChildren- 指示子对象是否可以接收焦点的标志。
  • mouseFocusEnabled- 点击时是否可以获得焦点。
  • tabFocusEnabled- 指示此对象是否可以通过 TAB 键获得焦点的标志 这类似于 Flash Player 使用的 tabEnabled 属性。这对于处理键盘输入的组件通常是正确的,但是控制栏中的某些组件将它们设置为 false,因为它们不应该从另一个组件(如编辑器)中窃取焦点。
于 2013-06-11T18:14:28.290 回答
0

在 AS3 中处理此问题的正确方法是通过 InteractiveObject 的 tabEnabled 属性。忘记 FLEX。

tabEnabled 属性控制 InteractiveObject 在鼠标单击时是否接收焦点并生成 mouseFocusChanged 事件。

我已经实现了非常精细的焦点更改机制和跟踪,根据我的经验,最好使用 tabEnabled 专门用于控制是否可以通过鼠标或 Tab 键接收焦点。

首先,对于 TextField 类型的 input、SimpleButtons 和具有 buttonMode = true 的 Sprites/MovieClips,tabEnabled 默认为 true。所以你会遇到这个默认值。尊重它比记住何时在何处覆盖它更容易。

其次,对于您希望在单击时获得焦点的自定义对象,tabEnabled 本质上是一个内置属性,用于控制 Tab 键和鼠标单击是否将焦点分配给对象。tabEnabled 实际上是一个糟糕的名字,因为它的功能确实类似于“canReceiveFocusViaKeyboardOrMouse”。这是因为任何 InteractiveObject 实例都可以分配给 stage.focus。除了覆盖默认行为之外,没有办法禁止 InteractiveObject 被分配焦点,因此 tabEnabled 是您想要使用的。

现在,说了这么多,您可以通过拦截 key_focus_change 和 mouse_focus_change 事件轻松覆盖默认行为。

Mouse_focus_change 只分派给当前具有焦点的对象。从技术上讲,当没有焦点时,舞台有焦点,所以如果你第一次点击某个东西,就会以舞台为目标生成事件。同样,如果您单击舞台,焦点将设置为空,但从技术上讲,舞台正在重新获得焦点。

Key_focus_change 功能类似,只是当舞台有焦点时,按 Tab 键不会 Tab 到 Flash 播放器内的对象;要么不会发生焦点更改,要么其他 HTML 控件将获得焦点。这是设计使然。同时,如果播放器中的对象确实具有焦点,则按 Tab 将循环通过可用的选项卡启用对象,而不会返回舞台。这也是设计使然。因此,例如,如果您在舞台上只有一个 tabEnabled 对象并且它具有焦点,则按 Tab 不会将焦点从它身上移开。它实际上会将焦点循环回自身并激活它的 focusRect (因为更改的来源是按键)。您可以关闭单个对象或舞台上全局的键更改激活的焦点矩形。

现在有趣的部分。我建议您在某些情况下实际拦截并防止 key_focus_change 的默认值,并为 tab 键实现自己的 key_down 处理程序。例如,如果您希望自己的控件子集接收焦点,则拦截 key_focus_change 事件并查看具有焦点的对象是否是您预定义的对象之一。如果是,则阻止默认设置,并允许您的制表键按下处理程序将焦点移动到循环中的下一个项目。您还可以使用此技术沿父链向上走,直到在循环中找到一个对象,假设该对象正在失去焦点,然后将焦点移动到预定义的焦点循环中的下一个项目。从本质上讲,您可以使 tab 键不那么细粒度,只关注可聚焦控件的子集,

边注

将 mouseChildren 设置为 false 只会阻止子级成为鼠标事件的目标,因此它们仍会为其父级的点击区域做出贡献。如果父级有 mouseEnabled = false,那么它将不会接收鼠标事件(尽管作为子级本身,它仍然可以作为父级的点击区域)。设置mouseEnable = false和mouseChildren = false,相当于设置mouseEnabled = false并将每个孩子的mouseEnabled属性设置为false。换句话说,设置mouseChildren = false 只是将每个子对象的mouseEnabled 属性单独设置为false 的一种快捷方式。

于 2015-01-20T22:39:22.143 回答