当元素获得或失去焦点时将发生焦点事件。
当您需要更改焦点,使其进入和离开视觉元素时,焦点事件非常有用。控件通常使用焦点事件来更改其内容,具体取决于焦点状态。例如,文本字段可以在未获得焦点时显示占位文本,或者对 FocusInEvent 作出反应以清除占位文本。
焦点可通过用户交互操作(例如 Tab 键或单击)或使用带有 element.Focus() 的 C# 脚本转到某个视觉元素上。
焦点事件分为两种不同的类型:
FocusOutEvent 和 FocusInEvent 事件。FocusEvent 和 BlurEvent 事件。所有焦点事件的基类是 FocusEventBase。
| 事件 | 描述 | 涓滴 | 冒泡 | 可取消 | 
|---|---|---|---|---|
| FocusOutEvent | 某一元素失去焦点前发送。 | ✔ | ✔ | |
| FocusInEvent | 某一元素获得焦点前发送。 | ✔ | ✔ | |
| BlurEvent | 某一元素失去焦点后发送。 | ✔ | ||
| FocusEvent | 某一元素获得焦点后发送。 | ✔ | 
The following section explains relevant properties unique to focus events. This isn’t a complete list of all properties within the focus event family. For a full list, see the FocusEventBase in the API documentation.
relatedTarget:包含作为事件次要目标的视觉元素。对于 FocusOut 和 Blur 事件,包含获取焦点的元素。对于 FocusIn 和 Focus 事件,包含失去焦点的元素。
| 事件 | target | relatedTarget | 
|---|---|---|
| Blur | 失去焦点的元素。 | 获得焦点的元素。 | 
| Focus | 获得焦点的元素。 | 失去焦点的元素。 | 
| focusIn | 获得焦点的元素。 | 失去焦点的元素。 | 
| focusOut | 失去焦点的元素。 | 获得焦点的元素。 | 
当元素即将失去焦点时发送 FocusOutEvent 事件。
target:将失去焦点的元素。
relatedTarget:将获得焦点的元素。
当元素即将获得焦点时发送 FocusInEvent 事件。
target:将获得焦点的元素。
relatedTarget:将失去焦点的元素。
当元素失去焦点后发送 BlurEvent 事件。
target:失去焦点的元素。
relatedTarget:获得焦点的元素。
当元素获得焦点后发送 FocusEvent 事件。
target:获得焦点的元素。
relatedTarget:失去焦点的元素。
以下示例显示如何在 TextField 中使用占位文本。
通过 UXML 创建元素后,脚本会为 TextField 分配一个占位文本。当 TextField 获得焦点时,FocusInEvent 会触发并清除占位文本。FocusOutEvent 将根据 TextField 内容切换占位模式。
要查看示例运行效果,请执行以下操作:
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
public class PlaceHolderExample : EditorWindow
{
    [MenuItem("Window/UI Toolkit/PlaceHolderExample")]
    public static void ShowExample()
    {
        PlaceHolderExample wnd = GetWindow<PlaceHolderExample>();
        wnd.titleContent = new GUIContent("PlaceHolderExample");
    }
    private bool placeHolderMode = true;
    private const string placeHolderText = "Write here";
    public void CreateGUI()
    {
        TextField textField = new TextField();
        textField.value = placeHolderText;
        rootVisualElement.Add(textField);
        textField.RegisterCallback<FocusInEvent>(OnFocusInTextField);
        textField.RegisterCallback<FocusOutEvent>(OnFocusOutTextField);
    }
    private void OnFocusInTextField(FocusInEvent evt)
    {
        // 如果文本字段刚刚获得焦点并且用户可能想要编写
        // 或编辑里面的文本,占位文本应该被清除(如果活动)
        if (placeHolderMode)
        {
            var textField = evt.target as TextField;
            textField.value = "";
        }
    }
    private void OnFocusOutTextField(FocusOutEvent evt)
    {
        // 如果用户完成编辑后文本字段为空,并且
        //元素失去焦点,将占位文本写入文本字段
        var textField = evt.target as TextField;
        placeHolderMode = string.IsNullOrEmpty(textField.value);
        if (placeHolderMode)
            textField.value = placeHolderText;
    }
}