1e41f4b71Sopenharmony_ci# Keyboard and Mouse Event 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ci 4e41f4b71Sopenharmony_ciKeyboard and mouse events refer to the input events of the peripheral keyboard and mouse. 5e41f4b71Sopenharmony_ci 6e41f4b71Sopenharmony_ci 7e41f4b71Sopenharmony_ci## Mouse Event 8e41f4b71Sopenharmony_ci 9e41f4b71Sopenharmony_ciThe supported mouse events include the events triggered by the peripheral mouse and touchpad. 10e41f4b71Sopenharmony_ci 11e41f4b71Sopenharmony_ciMouse events can trigger the following callbacks. 12e41f4b71Sopenharmony_ci 13e41f4b71Sopenharmony_ci| Name | Description | 14e41f4b71Sopenharmony_ci| ---------------------------------------- | ---------------------------------------- | 15e41f4b71Sopenharmony_ci| onHover(event: (isHover: boolean) => void) | Triggered when the mouse pointer enters or leaves the component.<br>**isHover**: whether the mouse pointer hovers over the component. The value **true** means that the mouse pointer enters the component, and the value **false** means that the mouse pointer leaves the component.| 16e41f4b71Sopenharmony_ci| onMouse(event: (event?: MouseEvent) => void) | Triggered when the component is clicked by a mouse button or the mouse pointer moves on the component. The **event** parameter indicates the timestamp, mouse button, action, coordinates of the clicked point on the entire screen, and coordinates of the clicked point relative to the component when the event is triggered.| 17e41f4b71Sopenharmony_ci 18e41f4b71Sopenharmony_ciWhen the component is bound to the **onHover** callback, you can use the [hoverEffect](../reference/apis-arkui/arkui-ts/ts-universal-attributes-hover-effect.md#hovereffect) attribute to set the hover effect of the component in hover state. 19e41f4b71Sopenharmony_ci 20e41f4b71Sopenharmony_ci 21e41f4b71Sopenharmony_ci **Figure 1** Mouse event data flow 22e41f4b71Sopenharmony_ci 23e41f4b71Sopenharmony_ci 24e41f4b71Sopenharmony_ci 25e41f4b71Sopenharmony_ci 26e41f4b71Sopenharmony_ci 27e41f4b71Sopenharmony_ciWhen ArkUI receives the mouse event, it checks whether the mouse event concerns pressing, lifting, or moving of the left mouse button, and then responds accordingly. 28e41f4b71Sopenharmony_ci 29e41f4b71Sopenharmony_ci 30e41f4b71Sopenharmony_ci- Yes: The mouse event is first converted into a touch event in the same position, and a collision test, gesture judgment, and callback response of the touch event are performed. The collision test and callback response of the mouse event are then performed. 31e41f4b71Sopenharmony_ci 32e41f4b71Sopenharmony_ci- No: Only the collision test and callback response of the mouse event are performed. 33e41f4b71Sopenharmony_ci 34e41f4b71Sopenharmony_ci 35e41f4b71Sopenharmony_ci>**NOTE** 36e41f4b71Sopenharmony_ci> 37e41f4b71Sopenharmony_ci>All touch events and gesture events that can be responded to by a single finger may be triggered and responded to by using the left mouse button. For example, to implement page redirection invoked by clicking a button with support for finger touches and left-clicks, you just need to bind one click event (**onClick**). If you want to implement different effects for the finger touch and the left-click, you can use the **source** parameter in the **onClick** callback to determine whether the current event is triggered by a finger or a mouse. 38e41f4b71Sopenharmony_ci 39e41f4b71Sopenharmony_ci 40e41f4b71Sopenharmony_ci### onHover 41e41f4b71Sopenharmony_ci 42e41f4b71Sopenharmony_ci 43e41f4b71Sopenharmony_ci```ts 44e41f4b71Sopenharmony_cionHover(event: (isHover: boolean) => void) 45e41f4b71Sopenharmony_ci``` 46e41f4b71Sopenharmony_ci 47e41f4b71Sopenharmony_ci 48e41f4b71Sopenharmony_ciTriggered when the mouse pointer enters or leaves the component. The **isHover** parameter indicates whether the mouse pointer hovers over the component. This event does not support custom bubbling settings. By default, event bubbling occurs between parent and child components. 49e41f4b71Sopenharmony_ci 50e41f4b71Sopenharmony_ci 51e41f4b71Sopenharmony_ciIf this API is bound to a component, it is triggered when the mouse pointer enters the component from outside and the value of **isHover** is **true**, or when the mouse pointer leaves the component and the value of **isHover** is **false**. 52e41f4b71Sopenharmony_ci 53e41f4b71Sopenharmony_ci 54e41f4b71Sopenharmony_ci>**NOTE** 55e41f4b71Sopenharmony_ci> 56e41f4b71Sopenharmony_ci>Event bubbling is an event propagation in the document object model (DOM) when an event is first handled by an element and then bubbles up to its parent element. 57e41f4b71Sopenharmony_ci 58e41f4b71Sopenharmony_ci 59e41f4b71Sopenharmony_ci 60e41f4b71Sopenharmony_ci 61e41f4b71Sopenharmony_ci```ts 62e41f4b71Sopenharmony_ci// xxx.ets 63e41f4b71Sopenharmony_ci@Entry 64e41f4b71Sopenharmony_ci@Component 65e41f4b71Sopenharmony_cistruct MouseExample { 66e41f4b71Sopenharmony_ci @State hoverText: string = 'Not Hover'; 67e41f4b71Sopenharmony_ci @State Color: Color = Color.Gray; 68e41f4b71Sopenharmony_ci 69e41f4b71Sopenharmony_ci build() { 70e41f4b71Sopenharmony_ci Column() { 71e41f4b71Sopenharmony_ci Button(this.hoverText) 72e41f4b71Sopenharmony_ci .width(200).height(100) 73e41f4b71Sopenharmony_ci .backgroundColor(this.Color) 74e41f4b71Sopenharmony_ci .onHover((isHover?: boolean) => { // Use the onHover API to listen for whether the mouse cursor is hovered over the button. 75e41f4b71Sopenharmony_ci if (isHover) { 76e41f4b71Sopenharmony_ci this.hoverText = 'Hovered!'; 77e41f4b71Sopenharmony_ci this.Color = Color.Green; 78e41f4b71Sopenharmony_ci } 79e41f4b71Sopenharmony_ci else { 80e41f4b71Sopenharmony_ci this.hoverText = 'Not Hover'; 81e41f4b71Sopenharmony_ci this.Color = Color.Gray; 82e41f4b71Sopenharmony_ci } 83e41f4b71Sopenharmony_ci }) 84e41f4b71Sopenharmony_ci }.width('100%').height('100%').justifyContent(FlexAlign.Center) 85e41f4b71Sopenharmony_ci } 86e41f4b71Sopenharmony_ci} 87e41f4b71Sopenharmony_ci``` 88e41f4b71Sopenharmony_ci 89e41f4b71Sopenharmony_ci 90e41f4b71Sopenharmony_ciIn this example, a **Button** component is created, with the initial background color of gray and the content of **Not Hover**. The component is bound to the **onHover** callback. In the callback, **this.isHovered** is set to the callback parameter **isHover**. 91e41f4b71Sopenharmony_ci 92e41f4b71Sopenharmony_ci 93e41f4b71Sopenharmony_ciWhen the mouse pointer moves from outside the button to inside the button, the callback is invoked, the value of **isHover** changes to **true**, the value of **isHovered** changes to **true**, the background color of the component changes to **Color.Green**, and the content changes to **Hovered!**. 94e41f4b71Sopenharmony_ci 95e41f4b71Sopenharmony_ci 96e41f4b71Sopenharmony_ciWhen the mouse pointer moves from inside the button to outside the button, the callback is invoked, the value of **isHover** changes to **false**, and the component restores to its initial style. 97e41f4b71Sopenharmony_ci 98e41f4b71Sopenharmony_ci 99e41f4b71Sopenharmony_ci 100e41f4b71Sopenharmony_ci 101e41f4b71Sopenharmony_ci 102e41f4b71Sopenharmony_ci### onMouse 103e41f4b71Sopenharmony_ci 104e41f4b71Sopenharmony_ci 105e41f4b71Sopenharmony_ci```ts 106e41f4b71Sopenharmony_cionMouse(event: (event?: MouseEvent) => void) 107e41f4b71Sopenharmony_ci``` 108e41f4b71Sopenharmony_ci 109e41f4b71Sopenharmony_ci 110e41f4b71Sopenharmony_ciTriggered when a mouse event occurs. It is triggered each time a mouse pointer action (**MouseAction**) is detected in the component. The parameter is a [MouseEvent](../reference/apis-arkui/arkui-ts/ts-universal-mouse-key.md#mouseevent) object, which indicates the mouse event that triggers the callback. This event supports custom bubbling settings. By default, event bubbling occurs between parent and child components. It is commonly used for customized mouse behavior logic processing. 111e41f4b71Sopenharmony_ci 112e41f4b71Sopenharmony_ci 113e41f4b71Sopenharmony_ciYou can use the **MouseEvent** object in the callback to obtain information about the triggered event, including the coordinates (**displayX**, **displayY**, **windowX**, **windowY**, **x**, and **y**), button ([MouseButton](../reference/apis-arkui/arkui-ts/ts-appendix-enums.md#mousebutton)), action ([MouseAction](../reference/apis-arkui/arkui-ts/ts-appendix-enums.md#mouseaction)), timestamp (**timestamp**), display area of the object that triggers the event ([EventTarget](../reference/apis-arkui/arkui-ts/ts-universal-events-click.md#eventtarget8)), and event source ([SourceType](../reference/apis-arkui/arkui-ts/ts-gesture-settings.md#sourcetype)). The **stopPropagation** callback of **MouseEvent** is used to set whether the current event blocks bubbling. 114e41f4b71Sopenharmony_ci 115e41f4b71Sopenharmony_ci 116e41f4b71Sopenharmony_ci>**NOTE** 117e41f4b71Sopenharmony_ci> 118e41f4b71Sopenharmony_ci>**MouseButton** indicates the physical mouse button being pressed or released that triggers the mouse event. The values are **Left**, **Right**, **Middle**, **Back**, **Forward**, and **None**. **None** indicates that no button is pressed or released, which means that the event is triggered by the mouse pointer moving on the component. 119e41f4b71Sopenharmony_ci 120e41f4b71Sopenharmony_ci 121e41f4b71Sopenharmony_ci 122e41f4b71Sopenharmony_ci```ts 123e41f4b71Sopenharmony_ci// xxx.ets 124e41f4b71Sopenharmony_ci@Entry 125e41f4b71Sopenharmony_ci@Component 126e41f4b71Sopenharmony_cistruct MouseExample { 127e41f4b71Sopenharmony_ci @State buttonText: string = ''; 128e41f4b71Sopenharmony_ci @State columnText: string = ''; 129e41f4b71Sopenharmony_ci @State hoverText: string = 'Not Hover'; 130e41f4b71Sopenharmony_ci @State Color: Color = Color.Gray; 131e41f4b71Sopenharmony_ci 132e41f4b71Sopenharmony_ci build() { 133e41f4b71Sopenharmony_ci Column() { 134e41f4b71Sopenharmony_ci Button(this.hoverText) 135e41f4b71Sopenharmony_ci .width(200) 136e41f4b71Sopenharmony_ci .height(100) 137e41f4b71Sopenharmony_ci .backgroundColor(this.Color) 138e41f4b71Sopenharmony_ci .onHover((isHover?: boolean) => { 139e41f4b71Sopenharmony_ci if (isHover) { 140e41f4b71Sopenharmony_ci this.hoverText = 'Hovered!'; 141e41f4b71Sopenharmony_ci this.Color = Color.Green; 142e41f4b71Sopenharmony_ci } 143e41f4b71Sopenharmony_ci else { 144e41f4b71Sopenharmony_ci this.hoverText = 'Not Hover'; 145e41f4b71Sopenharmony_ci this.Color = Color.Gray; 146e41f4b71Sopenharmony_ci } 147e41f4b71Sopenharmony_ci }) 148e41f4b71Sopenharmony_ci .onMouse((event?: MouseEvent) => { // Set the onMouse callback for the button. 149e41f4b71Sopenharmony_ci if (event) { 150e41f4b71Sopenharmony_ci this.buttonText = 'Button onMouse:\n' + '' + 151e41f4b71Sopenharmony_ci 'button = ' + event.button + '\n' + 152e41f4b71Sopenharmony_ci 'action = ' + event.action + '\n' + 153e41f4b71Sopenharmony_ci 'x,y = (' + event.x + ',' + event.y + ')' + '\n' + 154e41f4b71Sopenharmony_ci 'windowXY=(' + event.windowX + ',' + event.windowY + ')'; 155e41f4b71Sopenharmony_ci } 156e41f4b71Sopenharmony_ci }) 157e41f4b71Sopenharmony_ci Divider() 158e41f4b71Sopenharmony_ci Text(this.buttonText).fontColor(Color.Green) 159e41f4b71Sopenharmony_ci Divider() 160e41f4b71Sopenharmony_ci Text(this.columnText).fontColor(Color.Red) 161e41f4b71Sopenharmony_ci } 162e41f4b71Sopenharmony_ci .width('100%') 163e41f4b71Sopenharmony_ci .height('100%') 164e41f4b71Sopenharmony_ci .justifyContent(FlexAlign.Center) 165e41f4b71Sopenharmony_ci .borderWidth(2) 166e41f4b71Sopenharmony_ci .borderColor(Color.Red) 167e41f4b71Sopenharmony_ci .onMouse((event?: MouseEvent) => { // Set the onMouse callback for the column. 168e41f4b71Sopenharmony_ci if (event) { 169e41f4b71Sopenharmony_ci this.columnText = 'Column onMouse:\n' + '' + 170e41f4b71Sopenharmony_ci 'button = ' + event.button + '\n' + 171e41f4b71Sopenharmony_ci 'action = ' + event.action + '\n' + 172e41f4b71Sopenharmony_ci 'x,y = (' + event.x + ',' + event.y + ')' + '\n' + 173e41f4b71Sopenharmony_ci 'windowXY=(' + event.windowX + ',' + event.windowY + ')'; 174e41f4b71Sopenharmony_ci } 175e41f4b71Sopenharmony_ci }) 176e41f4b71Sopenharmony_ci } 177e41f4b71Sopenharmony_ci} 178e41f4b71Sopenharmony_ci``` 179e41f4b71Sopenharmony_ci 180e41f4b71Sopenharmony_ci 181e41f4b71Sopenharmony_ciBind the **onMouse** API to the button based on the **onHover** example. In the callback, the values of the callback parameters, such as **button** and **action**, are displayed. The same settings are performed on the outer **Column** container. The entire process can be divided into the following two actions: 182e41f4b71Sopenharmony_ci 183e41f4b71Sopenharmony_ci 184e41f4b71Sopenharmony_ci1. Moving the mouse pointer: When the mouse pointer is moved from outside the button to inside the button, only the **onMouse** callback of the **Column** is triggered. When the mouse pointer is moved to the button, as the **onMouse** event bubbles up by default, both the **onMouse** callbacks of the **Column** and **Button** components are invoked. In this process, the mouse pointer moves, but no mouse button is clicked. Therefore, in the displayed information, the value of **button** is 0 (enumerated value of **MouseButton.None**) and the value of **action** is **3** (enumerated value of **MouseAction.Move**). 185e41f4b71Sopenharmony_ci 186e41f4b71Sopenharmony_ci2. Clicking the mouse button: After the mouse pointer enters the **Button** component, the **Button** component is clicked twice, namely, left-click and right-click. 187e41f4b71Sopenharmony_ci Left-clicked: button = 1 (enumerated value of **MouseButton.Left**); action = 1 (enumerated value of **MouseAction.Press**); action = 2 (enumerated value of **MouseAction.Release**). 188e41f4b71Sopenharmony_ci 189e41f4b71Sopenharmony_ci Right-click: button = 2 (enumerated value of **MouseButton.Right**); action = 1 (enumerated value of **MouseAction.Press**); action = 2 (enumerated value of **MouseAction.Release**) 190e41f4b71Sopenharmony_ci 191e41f4b71Sopenharmony_ci 192e41f4b71Sopenharmony_ci 193e41f4b71Sopenharmony_ci 194e41f4b71Sopenharmony_ci 195e41f4b71Sopenharmony_ciTo prevent the mouse event from bubbling, call the **stopPropagation()** API. 196e41f4b71Sopenharmony_ci 197e41f4b71Sopenharmony_ci 198e41f4b71Sopenharmony_ci 199e41f4b71Sopenharmony_ci```ts 200e41f4b71Sopenharmony_ciclass ish{ 201e41f4b71Sopenharmony_ci isHovered:boolean = false 202e41f4b71Sopenharmony_ci set(val:boolean){ 203e41f4b71Sopenharmony_ci this.isHovered = val; 204e41f4b71Sopenharmony_ci } 205e41f4b71Sopenharmony_ci} 206e41f4b71Sopenharmony_ciclass butf{ 207e41f4b71Sopenharmony_ci buttonText:string = '' 208e41f4b71Sopenharmony_ci set(val:string){ 209e41f4b71Sopenharmony_ci this.buttonText = val 210e41f4b71Sopenharmony_ci } 211e41f4b71Sopenharmony_ci} 212e41f4b71Sopenharmony_ci@Entry 213e41f4b71Sopenharmony_ci@Component 214e41f4b71Sopenharmony_cistruct MouseExample { 215e41f4b71Sopenharmony_ci @State isHovered:ish = new ish() 216e41f4b71Sopenharmony_ci build(){ 217e41f4b71Sopenharmony_ci Column(){ 218e41f4b71Sopenharmony_ci Button(this.isHovered ? 'Hovered!' : 'Not Hover') 219e41f4b71Sopenharmony_ci .width(200) 220e41f4b71Sopenharmony_ci .height(100) 221e41f4b71Sopenharmony_ci .backgroundColor(this.isHovered ? Color.Green : Color.Gray) 222e41f4b71Sopenharmony_ci .onHover((isHover?: boolean) => { 223e41f4b71Sopenharmony_ci if(isHover) { 224e41f4b71Sopenharmony_ci let ishset = new ish() 225e41f4b71Sopenharmony_ci ishset.set(isHover) 226e41f4b71Sopenharmony_ci } 227e41f4b71Sopenharmony_ci }) 228e41f4b71Sopenharmony_ci .onMouse((event?: MouseEvent) => { 229e41f4b71Sopenharmony_ci if (event) { 230e41f4b71Sopenharmony_ci if (event.stopPropagation) { 231e41f4b71Sopenharmony_ci event.stopPropagation(); // Prevent the onMouse event from bubbling. 232e41f4b71Sopenharmony_ci } 233e41f4b71Sopenharmony_ci let butset = new butf() 234e41f4b71Sopenharmony_ci butset.set('Button onMouse:\n' + '' + 235e41f4b71Sopenharmony_ci 'button = ' + event.button + '\n' + 236e41f4b71Sopenharmony_ci 'action = ' + event.action + '\n' + 237e41f4b71Sopenharmony_ci 'x,y = (' + event.x + ',' + event.y + ')' + '\n' + 238e41f4b71Sopenharmony_ci 'windowXY=(' + event.windowX + ',' + event.windowY + ')'); 239e41f4b71Sopenharmony_ci } 240e41f4b71Sopenharmony_ci }) 241e41f4b71Sopenharmony_ci } 242e41f4b71Sopenharmony_ci } 243e41f4b71Sopenharmony_ci} 244e41f4b71Sopenharmony_ci``` 245e41f4b71Sopenharmony_ci 246e41f4b71Sopenharmony_ci 247e41f4b71Sopenharmony_ciTo prevent the mouse event of the child component (**Button**) from bubbling up to its parent component (**Column**), use the **event** parameter in the **onMouse** callback of **Button** to call the **stopPropagation** API. 248e41f4b71Sopenharmony_ci 249e41f4b71Sopenharmony_ci 250e41f4b71Sopenharmony_ci 251e41f4b71Sopenharmony_ci```ts 252e41f4b71Sopenharmony_cievent.stopPropagation() 253e41f4b71Sopenharmony_ci``` 254e41f4b71Sopenharmony_ci 255e41f4b71Sopenharmony_ci 256e41f4b71Sopenharmony_ciWith bubbling prevented, the mouse event on the **Button** component will trigger the **onMouse** callback of the **Button** component, but not the **onMouse** callback of the **Column** component. 257e41f4b71Sopenharmony_ci 258e41f4b71Sopenharmony_ci 259e41f4b71Sopenharmony_ci### hoverEffect 260e41f4b71Sopenharmony_ci 261e41f4b71Sopenharmony_ci 262e41f4b71Sopenharmony_ci```ts 263e41f4b71Sopenharmony_cihoverEffect(value: HoverEffect) 264e41f4b71Sopenharmony_ci``` 265e41f4b71Sopenharmony_ci 266e41f4b71Sopenharmony_ci 267e41f4b71Sopenharmony_ciSets the hover effect of the component in hover state. The parameter value type is **HoverEffect**. The **Auto**, **Scale**, and **Highlight** effects are preset and do not support customization. 268e41f4b71Sopenharmony_ci 269e41f4b71Sopenharmony_ci 270e41f4b71Sopenharmony_ci **Table 1** HoverEffect 271e41f4b71Sopenharmony_ci 272e41f4b71Sopenharmony_ci| Value| Description | 273e41f4b71Sopenharmony_ci| -------------- | ---------------------------------------- | 274e41f4b71Sopenharmony_ci| Auto | Default hover effect, which varies by component. | 275e41f4b71Sopenharmony_ci| Scale | Scale effect. When the mouse pointer is placed over the component, the component is scaled up from 100% to 105%. When the mouse pointer is moved away, the component is scaled down from 105% to 100%.| 276e41f4b71Sopenharmony_ci| Highlight | Background fade-in and fade-out effect. When the mouse pointer is placed over the component, a white layer with 5% opacity is applied to the background color of the component, resulting in a dimmed background. When the mouse pointer is moved away, the background color of the component is restored to the original style.| 277e41f4b71Sopenharmony_ci| None | No effect. | 278e41f4b71Sopenharmony_ci 279e41f4b71Sopenharmony_ci 280e41f4b71Sopenharmony_ci 281e41f4b71Sopenharmony_ci```ts 282e41f4b71Sopenharmony_ci// xxx.ets 283e41f4b71Sopenharmony_ci@Entry 284e41f4b71Sopenharmony_ci@Component 285e41f4b71Sopenharmony_cistruct HoverExample { 286e41f4b71Sopenharmony_ci build() { 287e41f4b71Sopenharmony_ci Column({ space: 10 }) { 288e41f4b71Sopenharmony_ci Button('Auto') 289e41f4b71Sopenharmony_ci .width(170).height(70) 290e41f4b71Sopenharmony_ci Button('Scale') 291e41f4b71Sopenharmony_ci .width(170).height(70) 292e41f4b71Sopenharmony_ci .hoverEffect(HoverEffect.Scale) 293e41f4b71Sopenharmony_ci Button('Highlight') 294e41f4b71Sopenharmony_ci .width(170).height(70) 295e41f4b71Sopenharmony_ci .hoverEffect(HoverEffect.Highlight) 296e41f4b71Sopenharmony_ci Button('None') 297e41f4b71Sopenharmony_ci .width(170).height(70) 298e41f4b71Sopenharmony_ci .hoverEffect(HoverEffect.None) 299e41f4b71Sopenharmony_ci }.width('100%').height('100%').justifyContent(FlexAlign.Center) 300e41f4b71Sopenharmony_ci } 301e41f4b71Sopenharmony_ci} 302e41f4b71Sopenharmony_ci``` 303e41f4b71Sopenharmony_ci 304e41f4b71Sopenharmony_ci 305e41f4b71Sopenharmony_ci 306e41f4b71Sopenharmony_ci 307e41f4b71Sopenharmony_ci 308e41f4b71Sopenharmony_ciThe default hover effect for the button is the **Highlight** effect. Therefore, the effects of **Auto** and **Highlight** are the same. The **Highlight** effect darkens the background color, **Scale** causes the component to scale, and **None** disables the hover effect. 309e41f4b71Sopenharmony_ci 310e41f4b71Sopenharmony_ci 311e41f4b71Sopenharmony_ci## Key Event 312e41f4b71Sopenharmony_ci 313e41f4b71Sopenharmony_ci### Key Event Data Flow 314e41f4b71Sopenharmony_ci 315e41f4b71Sopenharmony_ci 316e41f4b71Sopenharmony_ci 317e41f4b71Sopenharmony_ci 318e41f4b71Sopenharmony_ciAfter being triggered by a device such as a peripheral keyboard, a key event has its data processed and converted by the driver and multimodal input modules, and then is sent to the currently focused window. The window dispatches the received event, following the sequence below. The dispatch stops once the event is consumed. 319e41f4b71Sopenharmony_ci 320e41f4b71Sopenharmony_ci1. The window first dispatches the event to the ArkUI framework for invoking the **onKeyPreIme** callback bound to the component in focus as well as the page keyboard shortcuts. 321e41f4b71Sopenharmony_ci2. If the ArkUI framework does not consume the event, the window dispatches the event to the input method for key input. 322e41f4b71Sopenharmony_ci3. If the input method does not consume the event, the window dispatches the event to the ArkUI framework again for responding to the system default key event (for example, focus navigation) and for invoking the **onKeyEvent** callback bound to the component in focus. 323e41f4b71Sopenharmony_ci 324e41f4b71Sopenharmony_ciWhen a text box has focus and the input method is enabled, most key events are consumed by the input method. For example, a letter key is used by the input method to enter a letter in the text box, and an arrow key is used by the input method to switch to the desired candidate word. Yet, if a keyboard shortcut is bound to the text box, the shortcut responds to the event first, and the event will not be consumed by the input method. 325e41f4b71Sopenharmony_ci 326e41f4b71Sopenharmony_ciAfter the key event is sent to the ArkUI framework, it first identifies the complete focus chain, and then sends the key event from one node to the next, following the leaf-to-root path. 327e41f4b71Sopenharmony_ci 328e41f4b71Sopenharmony_ciThe key event process for the **Web** component differs from the aforementioned process. The **Web** component does not match keyboard shortcuts when **onKeyPreIme** returns **false**. The unconsumed key event will be re-dispatched back to ArkUI through **ReDispatch** during the third key press dispatch. It is within this **ReDispatch** that operations such as matching keyboard shortcuts are performed again. 329e41f4b71Sopenharmony_ci 330e41f4b71Sopenharmony_ci### onKeyEvent & onKeyPreIme 331e41f4b71Sopenharmony_ci 332e41f4b71Sopenharmony_ci 333e41f4b71Sopenharmony_ci```ts 334e41f4b71Sopenharmony_cionKeyEvent(event: (event: KeyEvent) => void): T 335e41f4b71Sopenharmony_cionKeyPreIme(event: Callback<KeyEvent, boolean>): T 336e41f4b71Sopenharmony_ci``` 337e41f4b71Sopenharmony_ci 338e41f4b71Sopenharmony_ci 339e41f4b71Sopenharmony_ciThe difference between the preceding two methods lies only in the triggering time. For details, see [Key Event Data Flow](#key-event-data-flow). The return value of **onKeyPreIme** determines whether the key event will be dispatched for the page keyboard shortcut, input method, and **onKeyEvent**. 340e41f4b71Sopenharmony_ci 341e41f4b71Sopenharmony_ci 342e41f4b71Sopenharmony_ciThe methods are triggered when the bound component has focus and a key event occurs on the component. The callback parameter [KeyEvent](../reference/apis-arkui/arkui-ts/ts-universal-events-key.md#keyevent) can be used to obtain the information about the key event, including [KeyType](../reference/apis-arkui/arkui-ts/ts-appendix-enums.md#keytype), [keyCode](../reference/apis-input-kit/js-apis-keycode.md#keycode), **keyText**, [KeySource](../reference/apis-arkui/arkui-ts/ts-appendix-enums.md#keysource), **deviceId**, **metaKey**, **timestamp**, and **stopPropagation**. 343e41f4b71Sopenharmony_ci 344e41f4b71Sopenharmony_ci 345e41f4b71Sopenharmony_ci 346e41f4b71Sopenharmony_ci```ts 347e41f4b71Sopenharmony_ci// xxx.ets 348e41f4b71Sopenharmony_ci@Entry 349e41f4b71Sopenharmony_ci@Component 350e41f4b71Sopenharmony_cistruct KeyEventExample { 351e41f4b71Sopenharmony_ci @State buttonText: string = ''; 352e41f4b71Sopenharmony_ci @State buttonType: string = ''; 353e41f4b71Sopenharmony_ci @State columnText: string = ''; 354e41f4b71Sopenharmony_ci @State columnType: string = ''; 355e41f4b71Sopenharmony_ci 356e41f4b71Sopenharmony_ci build() { 357e41f4b71Sopenharmony_ci Column() { 358e41f4b71Sopenharmony_ci Button('onKeyEvent') 359e41f4b71Sopenharmony_ci .defaultFocus(true) 360e41f4b71Sopenharmony_ci .width(140).height(70) 361e41f4b71Sopenharmony_ci .onKeyEvent((event?: KeyEvent) => { // Set the onKeyEvent event for the button. 362e41f4b71Sopenharmony_ci if(event){ 363e41f4b71Sopenharmony_ci if (event.type === KeyType.Down) { 364e41f4b71Sopenharmony_ci this.buttonType = 'Down'; 365e41f4b71Sopenharmony_ci } 366e41f4b71Sopenharmony_ci if (event.type === KeyType.Up) { 367e41f4b71Sopenharmony_ci this.buttonType = 'Up'; 368e41f4b71Sopenharmony_ci } 369e41f4b71Sopenharmony_ci this.buttonText = 'Button: \n' + 370e41f4b71Sopenharmony_ci 'KeyType:' + this.buttonType + '\n' + 371e41f4b71Sopenharmony_ci 'KeyCode:' + event.keyCode + '\n' + 372e41f4b71Sopenharmony_ci 'KeyText:' + event.keyText; 373e41f4b71Sopenharmony_ci } 374e41f4b71Sopenharmony_ci }) 375e41f4b71Sopenharmony_ci 376e41f4b71Sopenharmony_ci Divider() 377e41f4b71Sopenharmony_ci Text(this.buttonText).fontColor(Color.Green) 378e41f4b71Sopenharmony_ci 379e41f4b71Sopenharmony_ci Divider() 380e41f4b71Sopenharmony_ci Text(this.columnText).fontColor(Color.Red) 381e41f4b71Sopenharmony_ci }.width('100%').height('100%').justifyContent(FlexAlign.Center) 382e41f4b71Sopenharmony_ci .onKeyEvent((event?: KeyEvent) => { // Set the onKeyEvent event for the parent container <Column>. 383e41f4b71Sopenharmony_ci if(event){ 384e41f4b71Sopenharmony_ci if (event.type === KeyType.Down) { 385e41f4b71Sopenharmony_ci this.columnType = 'Down'; 386e41f4b71Sopenharmony_ci } 387e41f4b71Sopenharmony_ci if (event.type === KeyType.Up) { 388e41f4b71Sopenharmony_ci this.columnType = 'Up'; 389e41f4b71Sopenharmony_ci } 390e41f4b71Sopenharmony_ci this.columnText = 'Column: \n' + 391e41f4b71Sopenharmony_ci 'KeyType:' + this.buttonType + '\n' + 392e41f4b71Sopenharmony_ci 'KeyCode:' + event.keyCode + '\n' + 393e41f4b71Sopenharmony_ci 'KeyText:' + event.keyText; 394e41f4b71Sopenharmony_ci } 395e41f4b71Sopenharmony_ci }) 396e41f4b71Sopenharmony_ci } 397e41f4b71Sopenharmony_ci} 398e41f4b71Sopenharmony_ci``` 399e41f4b71Sopenharmony_ci 400e41f4b71Sopenharmony_ci 401e41f4b71Sopenharmony_ciIn the preceding example, **onKeyEvent** is bound to the **Button** component and its parent container **Column**. After the application opens and loads a page, the first focusable non-container component in the component tree automatically obtains focus. Set the **Button** component as the default focus of the current page. Because the **Button** component is a child node of the **Column** component, the **Column** component also obtains focus. For details about the focus obtaining mechanism, see [Focus Event](arkts-common-events-focus-event.md). 402e41f4b71Sopenharmony_ci 403e41f4b71Sopenharmony_ci 404e41f4b71Sopenharmony_ci 405e41f4b71Sopenharmony_ci 406e41f4b71Sopenharmony_ci 407e41f4b71Sopenharmony_ciAfter the application is opened, press the following keys in sequence: Space, Enter, Left Ctrl, Left Shift, Letter A, and Letter Z. 408e41f4b71Sopenharmony_ci 409e41f4b71Sopenharmony_ci 410e41f4b71Sopenharmony_ci1. Because the **onKeyEvent** event bubbles by default, the **onKeyEvent** callbacks of both **Button** and **Column** are invoked. 411e41f4b71Sopenharmony_ci 412e41f4b71Sopenharmony_ci2. Each key has two callbacks, which correspond to **KeyType.Down** and **KeyType.Up** respectively, indicating that the key is pressed and then lifted. 413e41f4b71Sopenharmony_ci 414e41f4b71Sopenharmony_ci 415e41f4b71Sopenharmony_ciTo prevent the key event of the **Button** component from bubbling up to its parent container **Column**, add the **event.stopPropagation()** API to the **onKeyEvent** callback of **Button**. 416e41f4b71Sopenharmony_ci 417e41f4b71Sopenharmony_ci 418e41f4b71Sopenharmony_ci 419e41f4b71Sopenharmony_ci```ts 420e41f4b71Sopenharmony_ci@Entry 421e41f4b71Sopenharmony_ci@Component 422e41f4b71Sopenharmony_cistruct KeyEventExample { 423e41f4b71Sopenharmony_ci @State buttonText: string = ''; 424e41f4b71Sopenharmony_ci @State buttonType: string = ''; 425e41f4b71Sopenharmony_ci @State columnText: string = ''; 426e41f4b71Sopenharmony_ci @State columnType: string = ''; 427e41f4b71Sopenharmony_ci 428e41f4b71Sopenharmony_ci build() { 429e41f4b71Sopenharmony_ci Column() { 430e41f4b71Sopenharmony_ci Button('onKeyEvent') 431e41f4b71Sopenharmony_ci .defaultFocus(true) 432e41f4b71Sopenharmony_ci .width(140).height(70) 433e41f4b71Sopenharmony_ci .onKeyEvent((event?: KeyEvent) => { 434e41f4b71Sopenharmony_ci // Use stopPropagation to prevent the key event from bubbling up. 435e41f4b71Sopenharmony_ci if(event){ 436e41f4b71Sopenharmony_ci if(event.stopPropagation){ 437e41f4b71Sopenharmony_ci event.stopPropagation(); 438e41f4b71Sopenharmony_ci } 439e41f4b71Sopenharmony_ci if (event.type === KeyType.Down) { 440e41f4b71Sopenharmony_ci this.buttonType = 'Down'; 441e41f4b71Sopenharmony_ci } 442e41f4b71Sopenharmony_ci if (event.type === KeyType.Up) { 443e41f4b71Sopenharmony_ci this.buttonType = 'Up'; 444e41f4b71Sopenharmony_ci } 445e41f4b71Sopenharmony_ci this.buttonText = 'Button: \n' + 446e41f4b71Sopenharmony_ci 'KeyType:' + this.buttonType + '\n' + 447e41f4b71Sopenharmony_ci 'KeyCode:' + event.keyCode + '\n' + 448e41f4b71Sopenharmony_ci 'KeyText:' + event.keyText; 449e41f4b71Sopenharmony_ci } 450e41f4b71Sopenharmony_ci }) 451e41f4b71Sopenharmony_ci 452e41f4b71Sopenharmony_ci Divider() 453e41f4b71Sopenharmony_ci Text(this.buttonText).fontColor(Color.Green) 454e41f4b71Sopenharmony_ci 455e41f4b71Sopenharmony_ci Divider() 456e41f4b71Sopenharmony_ci Text(this.columnText).fontColor(Color.Red) 457e41f4b71Sopenharmony_ci }.width('100%').height('100%').justifyContent(FlexAlign.Center) 458e41f4b71Sopenharmony_ci .onKeyEvent((event?: KeyEvent) => { // Set the onKeyEvent event for the parent container <Column>. 459e41f4b71Sopenharmony_ci if(event){ 460e41f4b71Sopenharmony_ci if (event.type === KeyType.Down) { 461e41f4b71Sopenharmony_ci this.columnType = 'Down'; 462e41f4b71Sopenharmony_ci } 463e41f4b71Sopenharmony_ci if (event.type === KeyType.Up) { 464e41f4b71Sopenharmony_ci this.columnType = 'Up'; 465e41f4b71Sopenharmony_ci } 466e41f4b71Sopenharmony_ci this.columnText = 'Column: \n' + 467e41f4b71Sopenharmony_ci 'KeyType:' + this.buttonType + '\n' + 468e41f4b71Sopenharmony_ci 'KeyCode:' + event.keyCode + '\n' + 469e41f4b71Sopenharmony_ci 'KeyText:' + event.keyText; 470e41f4b71Sopenharmony_ci } 471e41f4b71Sopenharmony_ci }) 472e41f4b71Sopenharmony_ci } 473e41f4b71Sopenharmony_ci} 474e41f4b71Sopenharmony_ci``` 475e41f4b71Sopenharmony_ci 476e41f4b71Sopenharmony_ci 477e41f4b71Sopenharmony_ci 478e41f4b71Sopenharmony_ci 479e41f4b71Sopenharmony_ciUse **OnKeyPreIme** to block the left arrow key input in the text box. 480e41f4b71Sopenharmony_ci```ts 481e41f4b71Sopenharmony_ciimport { KeyCode } from '@kit.InputKit'; 482e41f4b71Sopenharmony_ci 483e41f4b71Sopenharmony_ci@Entry 484e41f4b71Sopenharmony_ci@Component 485e41f4b71Sopenharmony_cistruct PreImeEventExample { 486e41f4b71Sopenharmony_ci @State buttonText: string = ''; 487e41f4b71Sopenharmony_ci @State buttonType: string = ''; 488e41f4b71Sopenharmony_ci @State columnText: string = ''; 489e41f4b71Sopenharmony_ci @State columnType: string = ''; 490e41f4b71Sopenharmony_ci 491e41f4b71Sopenharmony_ci build() { 492e41f4b71Sopenharmony_ci Column() { 493e41f4b71Sopenharmony_ci Search({ 494e41f4b71Sopenharmony_ci placeholder: "Search..." 495e41f4b71Sopenharmony_ci }) 496e41f4b71Sopenharmony_ci .width("80%") 497e41f4b71Sopenharmony_ci .height("40vp") 498e41f4b71Sopenharmony_ci .border({ radius:"20vp" }) 499e41f4b71Sopenharmony_ci .onKeyPreIme((event:KeyEvent) => { 500e41f4b71Sopenharmony_ci if (event.keyCode == KeyCode.KEYCODE_DPAD_LEFT) { 501e41f4b71Sopenharmony_ci return true; 502e41f4b71Sopenharmony_ci } 503e41f4b71Sopenharmony_ci return false; 504e41f4b71Sopenharmony_ci }) 505e41f4b71Sopenharmony_ci } 506e41f4b71Sopenharmony_ci } 507e41f4b71Sopenharmony_ci} 508e41f4b71Sopenharmony_ci``` 509