6

我有一个数字输入字段,可以在用户键入时通过状态设置新值。这工作正常。但是,如果我向它添加小数(toFixed),则光标将在仅输入一位数字后跳转到输入的末尾。例如,当我删除那里的内容并输入其他内容时,就会发生这种情况。如果我改为在第一个和小数点之间添加一个数字,则光标不会跳转。有没有人遇到过这种情况,解决方案是什么?

小提琴显示问题:https ://jsfiddle.net/Inverness/k04yvq1u/

constructor() {
    super()

    this.state = {
      number: 1
    }

    this.handleInputChange = this.handleInputChange.bind(this)
  }

  handleInputChange(event) {
    console.log(event.target.value)
    this.setState({
      number: event.target.value
    })
  }

  render() {
    return (
      <div>
        <input
          type="number"
          value={ parseFloat(this.state.number).toFixed(2) }
          onChange={ this.handleInputChange }
          />
      </div>
    )
  }
4

4 回答 4

5

我已经成功地使用onBlur事件处理程序在用户完成输入后将输入字段的格式简单地格式化为您需要的方式。

在表单字段标签中添加一些信息,即输入将被限制为 2 个小数位,这应该有助于缓解因更改用户提供的值而导致的任何 UX 问题。

 constructor() {
    super()

    this.state = {
      number: 1
    }

    this.handleInputChange = this.handleInputChange.bind(this)
    this.formatInput = this.formatInput.bind(this)
  }

  handleInputChange(event) {
    console.log(event.target.value)
    this.setState({
      number: event.target.value
    })
  }

  formatInput() {
    const num = this.state.number
    this.setState({
        number: parseFloat(num).toFixed(2)
    })
  }

  render() {
    return (
      <div>
        <input
          type="number"
          value={ this.state.number }
          onChange={ this.handleInputChange }
          onBlur={ this.formatInput }
          />
      </div>
    )
 }

JSFiddle

于 2019-08-22T21:19:25.977 回答
1

我有类似的事情发生。这里的主要问题是您正在重新格式化他们输入的内容。由于 react 是使用 javascript 来改变值,浏览器无法猜测光标应该去哪里,所以它只是跳到最后。我解决这个问题的方法是仅在用户输入与 toFixed 格式匹配的内容时更新。应该起作用的大致等效的东西是value={this.state.number}在您的输入上设置。然后 on 更改应如下所示:

handleInputChange = e => {
  let val = e.target.value
  if (/^[\d]*\.?[\d]{0,2}$/.test(val)) {
    this.setState({number: val})
  }
}

这样,输入值仍然被限制为两位小数的浮点格式,但用户可以更自由地键入它。

于 2019-08-22T21:13:16.867 回答
0

@ryan28561 的答案是正确的,但解决方案不是。

正如他所说,javascript 不知道光标应该在哪里,所以我建议如下:

不解析输入,而是在输入中添加样式或警告,以便用户意识到他的输入不正确。此外,在将号码用于任何任务之前,您可以对其进行格式化。

class TodoApp extends React.Component {
  constructor() {
    super()

    this.state = {
      number: '1',
      wrongInput: false, 
    }

    this.handleInputChange = this.handleInputChange.bind(this)
  }

  handleInputChange(event) {
    let val = event.target.value
    if (/^[\d]*\.?[\d]{0,2}$/.test(val)) {
        this.setState({number: val, wrongInput: false})
    } else {
        this.setState({number: val, wrongInput: true})
    }
  }

  render() {
    return (
      <div>
        <input
          //type="number"
          style={this.state.wrongInput ? { border: `solid 1px red`, outline: 'none'} : {}}
          value={this.state.number}
          onChange={ this.handleInputChange }
          />
      </div>
    )
  }
}
于 2019-08-22T21:29:08.297 回答
-1

您的 toFixed 函数正在更改输入值,因此您的输入会丢失光标,正如我建议的另一个答案中提到的那样,为了避免更改您的输入值,您也可以尝试使用 step 属性来更好地控制您的输入。

<input
    type="number"
    step="0.01"
    value={ this.state.number }
    onChange={ this.handleInputChange }
    defaultValue={ parseFloat(this.state.number).toFixed(2) }
/>
于 2019-08-22T21:19:55.847 回答