最近在项目中遇到一个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