删除charecter后保持插入符号相同

时间:2017-09-26 04:48:34

标签: javascript reactjs input cursor caret

我有简单的反应输入组件,只接受数字,每个键盘输入我检查输入并仅返回经验证的条目,在第三个字符后我将-字符添加到输入。一切正常但是当我从第一个第三个角色编辑/删除一个字符时,我的插入符号跳到最后一个位置它很烦人,我怎么能将插入符号放在同一个位置。

Link to working example

我的输入组件

class App extends Component {

    constructor(props){
        super(props)
        this.state = {
            value: ''
        }
    }

    render() {
        const {value} = this.state
        return (
        <div className="App">
            <input type="text" value={value} onChange={this._onChange}/>
        </div>
        )
    }

    _onChange = (e) => {
        this.setState({value: this._validate(e.target.value)})
    }

    _validate(string){
        return new Input(string)
            .filterNumbersOnly()
            .addSeparator()
            .getString()
    }

}

export default App;

这是我的字符串验证类

export default class Input{
    constructor(string){
        this.string = string
    }

    filterNumbersOnly(){
        const regex = /(\d)/g
            ,strArray = this.string.match(regex)
        this.string = strArray ? strArray.reduce((a,b) => { return `${a}${b}` }, '') : ''
        return this
    }

    addSeparator(){
        const charArray = this.string.split('')
        this.string =  charArray.reduce((a,b,index) => {
            if(index > 2 && index < 4) {
                return `${a}-${b}`
            }
            return `${a}${b}`
        }, '')
        return this
    }

    getString(){
        return this.string
    }
}

2 个答案:

答案 0 :(得分:0)

如果您可以保留选择范围和元素目标,然后在设置状态之后应用它,例如在设置状态回调上,就像这样:

 _onChange = (e) => {
        var r =[e.target.selectionStart,e.target.selectionEnd];
        var el = e.target;
        this.setState({value: this._validate(e.target.value)},()=>{
            //just to make sure you extend cursor in case of - addition
            if (r[1] === this.state.value.indexOf("-")+1)
              r[1]++;
            el.setSelectionRange(r[0], r[1]);
        })
    }

示例网址https://codesandbox.io/s/628q1rvnl3

答案 1 :(得分:0)

它解决了我的所有问题,回调setState中的init选择

let el = ev.target                
this.setState({
    sum: value
}, () => {
    el.setSelectionRange(1, 1)
})