防止子组件在其父组件获得时获得焦点

时间:2013-06-11 12:15:59

标签: flex flex4 focus

我有一个包含多个子组件的复合组件。当用户点击父组件时,它会收到焦点,但是其中一个子组件也会获得焦点,我对此不感兴趣。有没有办法防止这种情况或者焦点必然总是在可编辑(子)组件上?感谢。

2 个答案:

答案 0 :(得分: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 - 确定对象的子项是否启用了Tab。
  • tabEnabled - 指定此对象是否按Tab键顺序排列。

以下仅适用于Flex:

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

答案 1 :(得分:0)

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

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

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

首先,对于带有buttonMode = true的输入类型,SimpleButtons和Sprites / MovieClip的TextField,tabEnabled默认为true。所以你将遇到这个默认值。尊重它,比记住何时覆盖它更容易。

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

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

仅将Mouse_focus_change调度到当前具有焦点的对象。从技术上讲,当没有任何焦点时,舞台具有焦点,因此如果您第一次单击某些内容,将以舞台作为目标生成事件。同样,如果单击舞台,焦点将设置为null,但从技术上讲,舞台正在重新获得焦点。

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

现在有趣的部分。我建议您在某些情况下实际拦截并阻止key_focus_change的默认值,并为tab键实现自己的key_down处理程序。例如,如果您希望自己的控件子集接收焦点,请截取key_focus_change事件,并查看具有焦点的对象是否是您预定义的对象之一。如果是,则阻止默认值,并允许Tab键按下处理程序将焦点移动到循环中的下一个项目。您还可以使用此技术走向父链,直到在循环中找到对象,假设失去焦点,并将焦点移动到预定义焦点循环中的下一个项目。在本质上,您可以通过拦截和取消焦点更改或将焦点更改重定向到允许的父级来使Tab键不那么细粒度,专注于可聚焦控件的子集。

旁注

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