1# 如何自定义鼠标悬停/点击组件的背景色
2## 场景介绍
3在日常的鼠标操作中,当鼠标悬浮或点击某个元素时,该元素的背景色一般都会加深或者背景色发生变化,因此开发者可以根据自己的喜好进行开发设置。本文即为大家介绍这种操作的开发。
4
5## 效果呈现
6本例效果图如下:
7
8效果说明:鼠标悬浮于输入框上方,输入框的背景色不发生变化。鼠标悬浮于按钮上方,按钮的背景色会发生变化。在输入正确的手机号后点击按钮TextError不显示,否则输入框下方会出现提示语。
9
10![](figures/mouse.gif)
11
12
13## 运行环境
14本例基于以下环境开发,开发者也可以基于其他适配的版本进行开发:
15- IDE: DevEco Studio 4.0 Release
16- SDK: Ohos_sdk_public 4.0.10.13(API Version 10 Release)
17
18## 实现思路
19本例包含的关键操作及其实现方案如下:
20
21- 悬浮于TextInput组件和Button组件上方,组件背景色发生变化:通过onHover()事件去判断是否悬浮于组件上方去实现。
22- 按钮出现倒计时:通过自定义函数materOnClick()调用setInterval()直到时间为0s。
23- 输入框的状态:通过判断输入手机号与预留的手机号是否相同去发生不同状态。
24
25## 开发步骤
26本例详细开发步骤如下,开发步骤中仅展示相关步骤代码,全量代码请参考完整代码章节的内容。
271. 构建UI。
28    通过TextInput、Button、Text组件将UI框架搭建起来。
29    ```ts
30    build(){
31      Column(){
32        Text('验证码倒计时')
33          .fontSize(36).margin(20)
34        Row({space:10}){
35          TextInput({placeholder:"请输入手机号",text:this.Text})
36            .type(InputType.Normal)
37            .placeholderColor(Color.Gray)
38            .placeholderFont({
39                size:20,
40                weight:FontWeight.Normal,
41                style:FontStyle.Normal
42            })
43            .enterKeyType(EnterKeyType.Next)
44            .caretColor(Color.Blue)
45            .maxLength(11)
46            // 设置错误状态下提示的错误文本或者不显示错误状态
47            .showError(this.TextError)
48            .enableKeyboardOnFocus(false)
49            .width(200)
50            .height(50)
51            .backgroundColor(this.color1)
52            .onChange((value:string)=>{
53            this.Text = value;
54          })
55
56          Button(this.flag ? `${this.sec}`+ "s" :"验证码",{type: ButtonType.Normal})
57            .width(150)
58            .height(50)
59            .backgroundColor(this.color)
60            .fontSize(18)
61            .fontColor(Color.White)
62            .borderRadius(15)
63        }.height(60)
64      }.width('100%')
65      .height('100%')
66      .justifyContent(FlexAlign.Center)
67      .alignItems(HorizontalAlign.Center)
68      .backgroundColor('#A1E1D6')
69    }
70    ```
712. 鼠标悬浮于组件上背景颜色发生变化。
72    通过onHover()事件去判断isHover的boolean去设置组件的背景色。
73    ```ts
74    // 输入框的背景色变化
75    .onHover((isHover?:boolean,event?:HoverEvent):void=>{
76      if (isHover){
77        this.color1 = '#DECECE'
78      }else {
79        this.color1 = '#DECECE'
80      }
81    })
82    // 按钮的背景色变化
83    .onHover((isHover?:boolean,event?:HoverEvent):void=>{
84      if(isHover){
85        this.color = '#46CDD0'
86      }else {
87        this.color ='#3E84A6'
88      }
89    })
90    ```
913. 输入错误手机号时输入框的状态以及输入正确手机号时按钮的变化。
92    通过判断输入的手机号是否与预设手机号相同。如果相同,通过函数materOnClick(),按钮出现60s倒计时;如果不同,输入框下方出现错误状态提示文本并且点击按钮不发生变化。
93    ```ts
94    // 自定义倒计时函数
95    private materOnClick(){
96      let T = setInterval(()=>{
97        if (this.sec <= 0){
98          clearTimeout(T)
99        }else{
100          this.sec--
101        }
102      },1000)
103    }
104    ...
105    // 输入正确和错误手机号的TextInput的状态
106    .onClick(()=>{
107      if (this.Text == this.PhoneNumber){
108        this.flag = true;
109        this.TextError = undefined;
110        this.materOnClick()
111      }else {
112        this.TextError = '请输入正确的手机号';
113        this.Text = '';
114      }
115    })
116    ```
117
118## 完整示例代码
119完整示例代码如下:
120```ts
121@Entry
122@Component
123struct Index{
124  @State Text: string = ''
125  @State sec: number = 60
126  @State flag: boolean = false
127  @State color: string = '#46CDD0'
128  @State color1:string = '#DECECE'
129  @State TextError :string | undefined = undefined
130  @State PhoneNumber: string = '13888888888'
131    private materOnClick(){
132    let T = setInterval(()=>{
133      if (this.sec <= 0){
134        clearTimeout(T)
135      }else{
136        this.sec--
137      }
138    },1000)
139  }
140
141  build(){
142    Column(){
143      Text('验证码倒计时')
144        .fontSize(36).margin(20)
145      Row({space:10}){
146        TextInput({placeholder:"请输入手机号",text:this.Text})
147          .type(InputType.Normal)
148          .placeholderColor(Color.Gray)
149          .placeholderFont({
150            size:20,
151            weight:FontWeight.Normal,
152            style:FontStyle.Normal
153          })
154          .enterKeyType(EnterKeyType.Next)
155          .caretColor(Color.Blue)
156          .maxLength(11)
157          .showError(this.TextError)
158          .enableKeyboardOnFocus(false)
159          .onChange((value:string)=>{
160            this.Text = value;
161          })
162          .width(200)
163          .height(50)
164          .backgroundColor(this.color1)
165          .onHover((isHover?:boolean,event?:HoverEvent):void=>{
166            if (isHover){
167              this.color1 = '#DECECE'
168            }else {
169              this.color1 = '#DECECE'
170            }
171          })
172        Button(this.flag ? `${this.sec}`+ "s" :"验证码",{type: ButtonType.Normal})
173          .width(150)
174          .height(50)
175          .backgroundColor(this.color)
176          .fontSize(18)
177          .fontColor(Color.White)
178          .borderRadius(15)
179          .onHover((isHover?:boolean,event?:HoverEvent):void=>{
180            if(isHover){
181              this.color = '#46CDD0'
182            }else {
183              this.color ='#3E84A6'
184            }
185          })
186          .onClick(()=>{
187            if (this.Text == this.PhoneNumber){
188              this.flag = true;
189              this.TextError = undefined;
190              this.materOnClick()
191            }else {
192              this.TextError = '请输入正确的手机号';
193              this.Text = '';
194            }
195          })
196      }.height(60)
197    }.width('100%')
198    .height('100%')
199    .justifyContent(FlexAlign.Center)
200    .alignItems(HorizontalAlign.Center)
201    .backgroundColor('#A1E1D6')
202  }
203}
204
205```
206
207## 参考
208
209[TextInput](../application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-textinput.md)
210
211[鼠标事件](../application-dev/reference/apis-arkui/arkui-ts/ts-universal-mouse-key.md)
212
213[定时器](../application-dev/reference/common/js-apis-timer.md)