input中文输入法下的bug

最近在项目中遇到一个input中文输入法有bug的问题

业务要求这个input只能输入大于0的正整数,要求限制不能输入.或者中文,当使用input type='number'的时候,不能限制中文的输入,虽然取不到值,但是还是能展示出来

于是乎就有了这个代码

<Input
      value={value}
      onChange={(v) => {
        let value = v.target.value;
        if (inputStatus) {
          if (
            value.length > 0 &&
            /^\+?[0-9]\d*$/.test(value[value.length - 1])
          ) {
            setValue(v.target.value);
          }
          if (!value) {
            setValue(v.target.value);
          }
          if (value == 0) {
            setValue("");
          }
      }}

    />

 然后在测视里发现,谷歌游览器,微软输入法中文输入的情况,会莫名其妙把我输入的内容替换掉

一番研究,究其原因是游览器和输入法对onchange的调用机制不同,这里设及到三个方法,都是在中文输入法的情况下

 onCompositionStart               开始输入的时候调用

 onCompositionUpdate           输入中,一直调用,每输入一个字符都会调用

onCompositionEnd                  结束输入的时候调用一次

针对不一样的游览器和输入法调用有点小差别--这里只测试了火狐和谷歌

以下是火狐游览器,在微软输入法或者搜狗输入法的情况下 

 onCompositionStart         //中文输入法下,开始输入的时候会调用一次

 onCompositionUpdate         //中文输入法下,开始输入后会调用一次,之后每输入一个字符会调用一次,结束输入前调用一次,按enter或者shift结束在输入前不会调用

 onchange        //火狐游览器除结束输入前调用的onCompositionUpdate,其他每一次调用onCompositionUpdate都会调用onchange

onCompositionEnd        //中文输入法下,结束输入的时候会调用一次

以下的是谷歌游览器  谷歌游览器在搜狗中文输入法下不调用

 onCompositionStart         //中文输入法下,开始输入的时候会调用一次

 onCompositionUpdate         //中文输入法下,开始输入后会调用一次,之后每输入一个字符会调用一次,结束输入前调用一次,按enter或者shift结束在输入前同样会调用

 onchange        //谷歌游览器每一次调用onCompositionUpdate都会调用onchange

onCompositionEnd        //中文输入法下,结束输入的时候会调用一次

我是为了实现功能,没做比较完善的封装,有能力的可以自行修改哈

import {useState} from 'react'
 import { Input } from "antd";
const App=()=>{
  const [value, setValue] = useState('')
  const [inputStatus, setInputStatus] = useState(true)//这里搞一个变量来判断我当前处在什么状态,输入中文中,还是输入中文后
  const [nowValue,setNowValue]=useState('')//存储输入中文之前的Value的值
  const composition = (evl) => {
    if (evl.type == "compositionend") {
      setInputStatus(true)
      setValue(nowValue);//结束的时候把储存的值重新赋给value就成功绕过中文啦
    } else {
      if (inputStatus) {
        setNowValue(value)//开始输入中文的时候储存以下现在的值
      }
      setInputStatus(false)
    }
  }
return (
  <div style={{ width: "170px" }}>
    <Input
      value={value}
      onChange={(v) => {
        console.log("onchange");
        let value = v.target.value;
        if (inputStatus) {//判断我当前处于啥状态
          if (
            value.length > 0 &&
            /^\+?[0-9]\d*$/.test(value[value.length - 1])
          ) {
            setValue(v.target.value);
          }
          if (!value) {
            setValue(v.target.value);
          }
          if (value == 0) {
            setValue("");
          }
        } else {
          setValue(value);
        }
      }}
      onCompositionStart={composition} //中文输入法下,开始输入的时候会调用一次
      onCompositionUpdate={composition} //中文输入法下,开始输入后会调用一次,之后每输入一个字符会调用一次,结束输入前调用一次,按enter或者shift结束在输入前不会调用,,谷歌都会调用
      onCompositionEnd={composition} //中文输入法下,结束输入的时候会调用一次
    />
  </div>
);
}
export default App

给我启发的文章:---解决 input 输入框在中文输入法下的 bug

还有个更详细的描述---解决 React 中的 input 输入框在中文输入法下的 bug

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java InputMethod 输入法的实现需要以下步骤: 1. 创建一个实现了 javax.swing.InputMethod 接口的类。 2. 实现 InputMethod 接口中的以下方法: (1)activate()方法:用于激活输入法,可以在该方法中实现输入法界面的显示。 (2)deactivate()方法:用于关闭输入法,可以在该方法中实现输入法界面的隐藏。 (3)getControlObject()方法:用于获取输入法控制对象,可以在该方法中实现输入法控制界面的显示。 (4)setCompositionEnabled(boolean enabled)方法:用于设置是否启用输入法的组合输入模式。 (5)setInputMethodContext(InputMethodContext context)方法:用于设置输入法上下文,该方法将在输入法初始化时被调用。 (6)dispose()方法:用于释放输入法资源。 (7)caretPositionChanged(InputMethodEvent event)方法:用于处理光标位置变化事件。 (8)inputMethodTextChanged(InputMethodEvent event)方法:用于处理输入法文本变化事件。 (9)keyTyped(KeyEvent event)方法:用于处理键盘输入事件。 3. 在实现类中创建输入法界面和输入法控制界面。 4. 在实现类中实现与输入法相关的业务逻辑。 5. 创建一个实现了 javax.swing.InputMethodDescriptor 接口的类,用于描述输入法。 6. 实现 InputMethodDescriptor 接口中的以下方法: (1)getInputMethodDisplayName()方法:用于获取输入法名称。 (2)getInputMethodIcon()方法:用于获取输入法图标。 (3)getLocale()方法:用于获取输入法所支持的语言环境。 (4)createInputMethod()方法:用于创建输入法实例。 7. 在应用程序中注册输入法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值