当前位置:   article > 正文

解决type=number的input可以输入+-e符号的情况_input type=number

input type=number

输入框input标签设置type="number"的目的就是为了规避用户输入数字以外的内容。然而,在html的w3c标准里,e认定为自然对数中的无理数常量,+-则是表示正负,生产中有时不需要甚至禁止输入这些。

1.值改变时,替换其中非数字内容(效果不好)

为输入框绑定事件,去除掉其中非数字和小数点部分。
onchange事件其实更接近于onblur,失焦且新旧值不等时才触发。oninput可做到输入单个字符就触发。

此外,网上还有使用onkeyup方法,监听按键抬起事件,除CtrlAltShiftEsc等键。(说关机键的请回炉重造。)
值得注意的是,onkeydown时value尚未改变,无法监听值并替换。

function setNum(e){
	e.value=e.value.replace(/[^0-9.]/g,"");
}
  • 1
  • 2
  • 3

在各个方法中,输入+-e后,监听input的值,不论是e.value还是$(e).val(),打印出来都是空,而(不替换符号时)页面上有显示内容。
起初以为是jQuery或者项目中的其他插件的影响,后单独起一个demo,效果也是如此。

<input type="number" oninput="setNum(this)">
  • 1
function setNum(e){
	console.log(e.value);
	// e.value = e.value.replace(/[^0-9.]/g,"");
}
  • 1
  • 2
  • 3
  • 4

inputDemo
不仅如此,小数点输入后仍然被触发清除,而焦点在最左边。
输入+-e后替换的也是整体而未保留数字。
输入1.后value=1,以上代码就会将其替换为1。
输入1e后value为空,会直接替换掉内容为空string。
所以,我不知道别人是怎么实现的,我这里行不通。
后来想想,估计是type=text吧,这样不仅没有原生的加减,图标点击加减功能,没有step属性,而且默认为文本输入,输入后闪现再消失,用户体验不好。

2.手动保存旧值,监听按键

如图,当我输入1.的时候,打印出来是1,其原生属性valueAsNumber=1我也能理解,为毛value=1,输入并显示e的时候,value=""valueAsNumber=NaN,你既然判断e为数字可以显示,真是当面一套背后一套。导致我没法从input的任何属性中找到其显示的内容,也就没法从value值判断是否输入+-e

value

于是想到了一个方法,在当前页面存储一个变量,记录该输入框的旧值,若按键是+-e则将value(此时value="")替换为旧值
注意触发onkeydownonkeyuponchangeoninput等方法的顺序及关系。而且监听按键的范围还不一样。
多个输入框则需要定义并寻找对应变量,所以我就给input定义两个自定义属性。

<input type="number" oninput="setNum(this)" onkeydown="downTest(this)" diyValue="" diyKey=false>
  • 1
function setNum(e) {
    if (e.diyKey) {
        e.value = e.diyValue;
    } else {
        e.diyValue = e.value;
    }
}

function downTest(e) {
    console.log(event.keyCode);
    e.diyKey = event.keyCode === 69 || event.keyCode === 187 || event.keyCode === 189;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

3.键入事件拦截(最优解)

监听键入事件keypress,区别于keydown事件,该事件不监听特殊键,如CtrlShift

document.getElementById("test").addEventListener('keypress', function (e) {
    let restricted = "+-e";
    let key = e.keyCode || e.which;
    for (let i = 0; i < restricted.length; i++) {
        if (restricted.charCodeAt(i) === key) {
            e.returnValue = false;
        }
    }
    return true;
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

4.自定义标签

参考:https://developer.mozilla.org/zh-CN/docs/Web/API/Web_components/Using_custom_elements

class CustomInput extends HTMLInputElement {
    constructor() {
        super();
        this.addEventListener('input', this.handleInput.bind(this));
    }

    handleInput(event) {
        const val = event.target.value;
        this.value = val.replace(/\D/g, '');
    }
}

customElements.define('custom-input', CustomInput, {extends: 'input'});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

使用:

<input is="custom-input"/>
  • 1

其中custom-input对应customElements.define()的第一个参数,必须单词+-+单词严格命名。听说js其实有伪编译过程,class及define方法,可以不用在onload后触发。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/549548
推荐阅读
相关标签
  

闽ICP备14008679号