【问题标题】:Keep caret same position after removing charecter删除字符后保持插入符号相同的位置
【发布时间】:2017-09-26 04:48:34
【问题描述】:

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

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
    }
}

【问题讨论】:

    标签: javascript reactjs input caret


    【解决方案1】:

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

     _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

    【讨论】:

      【解决方案2】:

      它解决了我所有的问题,在回调 setState 中初始化选择

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-06
        • 2019-09-16
        • 1970-01-01
        • 2013-04-20
        • 1970-01-01
        相关资源
        最近更新 更多