【问题标题】:Prevent user from inputting a number outside of value range防止用户输入超出值范围的数字
【发布时间】:2019-06-17 11:30:41
【问题描述】:

我使用这个堆栈问题作为验证输入的基础。我有一个范围滑块,用户可以在其中输入一个介于 8 和 24 之间的数字。如果用户输入的数字超过 24,它应该转到 24。如果用户输入的数字小于 8,它应该转到 8。

我遇到的问题是,如果用户输入的数字超过 24,它会自动变为 8。有什么想法吗?

Prevent user from typing in input at max value

$('#interestValue').on('keyup keydown', function(e){
   if ($(this).val() > 24 
        && e.keyCode !== 46 // keycode for delete
        && e.keyCode !== 8 // keycode for backspace
       ) {
       e.preventDefault();
       $(this).val(24);
       doMath();
    }

     if ($(this).val() < 8
        && e.keyCode !== 46 // keycode for delete
        && e.keyCode !== 8 // keycode for backspace
       ) {
       e.preventDefault();
       $(this).val(8);
       doMath();
    }
});

【问题讨论】:

  • 我前两天回答了一个很相似的问题:stackoverflow.com/questions/54305302/…
  • 我觉得input 事件会是更好的方法,而不是上下键。
  • input 事件涵盖了 Chrome 和其他浏览器放入数字字段的向上/向下箭头按钮。

标签: javascript jquery


【解决方案1】:

除了需要确保您比较的是数字而不是字符串之外,您还不能安全地在 keyupkeydowninput 上执行此操作——因为这些事件在每次击键时都会触发,因此用户不可能输入(例如)“23”,因为当他们输入第一个“2”时,它会立即变成“8”。

请改用change 事件,它可以让用户在您开始从下方更改输入之前完成他们的预期输入。 (这也允许您简化代码,因为您不再需要检查“退格”和“删除”键事件。)

$('#interestValue').on('change', function(e){
   e.preventDefault();
   var val = Number($(this).val()); // ensure you're not accidentally comparing strings
   if (val > 24) {
       $(this).val(24);
    } else if (val < 8) {
       $(this).val(8);
    } else if (isNaN(val)) {
       console.log("Input wasn't a number... you probably want to handle this case")
    }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="interestValue">

【讨论】:

  • 我的问题是我有一个 ajax 函数,它会在输入后立即计算我的公式,所以用户仍然可以输入“9999”,直到他们按下回车键。有什么方法可以验证这一点,所以当用户没有按 Enter 键时它仍然会触发?
  • @chronotrigga 可能这种方法没有意义。你怎么知道用户输入完毕?
  • 出于完全相同的原因,您也不应该在每次击键时调用该 ajax 函数。 “2”可能是无效输入,也可能是有效输入的第一位;除非您等待用户完成,否则您的代码不可能知道其中的区别。
  • 我明白你们现在的意思了,因为用户输入第一个“2”并且事件触发,所以无法输入 23 进行验证......嗯......也许最好只是使用 keyup 等将其默认为最小 8
【解决方案2】:

我强烈建议在这里创建一个原生 Web 组件。我将向您展示自定义内置组件的基本设置,其中包含一个已经可以工作且没有外部依赖项的组件:

class DecimalInput extends HTMLInputElement {
  constructor() {
    super();
    this.addEventListener('change', (e) => {
      const val = parseFloat(this.value),
            min = parseFloat(this.min),
            max = parseFloat(this.max),
            step = parseFloat(this.step);
            
      if (val%step !== 0) {
        this.value = Math.round(val/step) * step
      }
      if (val > max) {
        this.value = max
      }
      if (val < min) {
        this.value = min
      }
    })
  }
}

customElements.define('decimal-input', DecimalInput, { extends: 'input' })
<label><input type="number" is="decimal-input" min="8" max="24" step="1" value="16" /> Allows input from 8-24</label>
<hr />
<label><input type="number" is="decimal-input" min="0" max="1024" step="16" value="16" /> Allows input from 0-1024, in 16-steps</label>

这个组件已经非常接近您的要求了。在此基础上使用它进行自己的改进。

【讨论】:

  • 我看到了您的评论并感谢您的回答。我知道您在这里使用了更改事件,这意味着该事件在用户完成输入后触发。有什么方法可以在输入期间验证这一点?我的公式计算在输入过程中实时完成所有工作。
  • 正如@Daniel Beck 所说,这没有意义。用户应该如何输入21?使用您的方法,用户键入 2 并立即被您的 min 值替换。
  • 你说得对。嗯。也许最好的选择是只强制最小值。只是以为会有不同的方式,但我明白了!
【解决方案3】:

我建议使用另一个事件处理用户的值,例如“模糊”。 使用模糊事件,您可以在用户将焦点更改为另一个字段时触发计算,这更容易控制,因为您在尝试其他内容之前等待用户输入。或者,您始终可以尝试在事件函数内部或在验证当前用户输入值的外部函数中使用 setTimeout。不过要小心这个,当前输入的值很可能是用户之前输入的值。

【讨论】:

    【解决方案4】:

    如果对任何人有帮助,我想我会在这里发布我的答案。我能够完成这项工作——不是以对开发人员最友好的方式,而是以一种很好的 hack 方式。

    $('#interestValue').on('keyup keydown', function(e){
    
        if ($(this).val() > 24 
            && e.keyCode !== 46 // keycode for delete
            && e.keyCode !== 8 // keycode for backspace
        ) {
           e.preventDefault();
           $(this).val(24);
           doMath();
        }
    
         if ($(this).val() < 8 && $(this).val() > 2
            && e.keyCode !== 46 // keycode for delete
            && e.keyCode !== 8 // keycode for backspace
           ) {
           e.preventDefault();
           $(this).val(8);
           doMath();
        }
    });
    

    【讨论】:

    • 这似乎并没有解决您原始代码的任何问题;您仍然可能在比较字符串而不是数字,并且当用户尝试键入时,您仍在更改用户的输入...
    猜你喜欢
    • 2021-12-09
    • 2015-01-09
    • 1970-01-01
    • 2022-08-14
    • 1970-01-01
    • 2021-05-14
    • 1970-01-01
    • 1970-01-01
    • 2015-06-24
    相关资源
    最近更新 更多