状态机实现金额输入限制

该博客介绍了一种利用状态机来动态判断输入字符是否合法的方法,特别是在处理金钱输入时,确保只允许数字和一个小数点,并限制小数点后的位数不超过两位。通过监听键盘事件并阻止非法字符的输入,提高了用户体验。代码示例展示了如何实现这个功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

利用状态机判断输入的下一位字符是否能被接受,来决定是否阻止按键事件。此方法的优点是能动态地确定下一个按键是否有效,相较于正则的新思路。

<html>
    <head></head>
    <body>
        <input id="money"/>
        <script>
            let inputElem = document.getElementById("money");
            function isMoney(text,e){
                let shouldPrevent = false;
                let dotOnce = false;
                let fractionCount = 0;
                function start(code){
                    if(typeof code === "undefined") return end;
                    if(!/[\d]/.test(code)){//第一个只能接受数字
                        shouldPrevent = true;
                        return end;
                    }else{
                        return number;
                    }
                }
                function number(code){
                    if(typeof code === "undefined") return end;
                    if(code === "."){
                        return dot(code);
                    }else{
                        if(fractionCount >=2){//小数不能多于2位
                            shouldPrevent = true;
                            return end;
                        }
                        if(dotOnce){fractionCount++;}
                        return number;
                    }
                }
                function dot(code){
                    if(typeof code === "undefined") return end;
                    if(dotOnce){//小数点只有一个
                        shouldPrevent = true;
                        return end;
                    }
                    dotOnce = true;
                    return number;
                }
                function end(){
                    if(shouldPrevent){
                        e.preventDefault();
                    }
                }
                let mochine = start;
                let index = 0;
                do{
                    mochine = mochine(text[index]);
                    index++;
                } while(mochine!==end)
                mochine();//执行终结函数退出
            }
            function makeMap(str, expectsLowerCase) {
                const map = Object.create(null);
                const list = str.split(',');
                for (let i = 0; i < list.length; i++) {
                    map[list[i]] = true;
                }
                return expectsLowerCase ? val => !!map[val.toLowerCase()] : val => !!map[val];
            }
            const whiteList = "Backspace,ArrowLeft,ArrowRight";//不会被阻止的按键
            const inWhiteList = makeMap(whiteList);
            inputElem.addEventListener("keydown",function(e){
                const value = e.target.value;
                const key = e.key;
                const nextStr = value + key;
                if(!inWhiteList(key)){//不在白名单里的按键
                    if(!/[\d\.]+/.test(nextStr)){//数字和小数点为有效字符
                        e.preventDefault();
                    }else{
                        isMoney(nextStr,e);  
                    }
                }
            });
        </script>
    </body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值