Javascript 如何检测输入字段上的编程值更改

Javascript 如何检测输入字段上的编程值更改,javascript,html,validation,input,event-handling,Javascript,Html,Validation,Input,Event Handling,关于这个话题,我读过几个问题,但似乎没有一个能提供这个问题的一般解决方案。所有的答案似乎都指向一些特定的案例 我有一个简单的输入字段 <input type="number" id="inputBox" min="0" max="255" step="1" /> 所有这些对于用户输入来说似乎都很好 var inputBox=document.getElementById(“inputBox”); addEventListener(“输入”,函数(){ 验证输入(本); }); i

关于这个话题,我读过几个问题,但似乎没有一个能提供这个问题的一般解决方案。所有的答案似乎都指向一些特定的案例

我有一个简单的输入字段

<input type="number" id="inputBox" min="0" max="255" step="1" />
所有这些对于用户输入来说似乎都很好

var inputBox=document.getElementById(“inputBox”);
addEventListener(“输入”,函数(){
验证输入(本);
});
inputBox.addEventListener(“向下键”,函数(e){
验证输入(此,e);
});
功能验证输入(elm,e){
//处理keydown事件
如果(e){
//不允许使用浮点数(如果不是预期的)
如果(!isFloat(elm.step)){
如果(e.key==”){
e、 预防默认值();
}
}
}
//处理输入事件
否则{
//不允许前导零
而(elm.value.length>1&&elm.value[0]=“0”){
elm.value=elm.value.toString().slice(1);
}
//输入值应介于最小值和最大值之间
if(elm.validity.rangeUnderflow){
elm.value=elm.min;
}else if(elm.validity.rangeOverflow){
elm.value=elm.max;
}
}
}
函数isFloat(f){
var f=浮点数(f);
var地板=数学地板(f);
var分数=f-地板;
如果(分数>0){
返回true;
}
返回false;
}

因此,对我来说,事件侦听器根本不会被触发,因为它们没有发生。当以编程方式更改值时,字段上没有“keydown”,因为DOM中没有触发任何事件

对我来说,我认为您还应该连接其他事件处理程序,这更“页面级别”。在查看jQuery事件类别()时,如果您将这些事件分配给页面本身会怎么样?在鼠标x\y改变时,在页面上输入\leave和focus\blur


使用所有这些事件似乎有点过分,但这似乎是一个独特的情况。对我来说,你从来都不信任用户输入,所以我倾向于在用户提交数据时重新计算\验证数据,但在这种情况下,如果数据没有提交给你,我认为通过某些页面级事件而不是输入特定事件触发这些项,可能会让你度过难关

您可以在这样更改值后触发事件programmaticaly

var inputBox=document.getElementById(“inputBox”);
addEventListener(“输入”,函数(){
控制台日志(“输入”);
//输入值应介于最小值和最大值之间
如果(此.validity.rangeUnderflow){
this.value=this.min;
}
else if(this.validity.rangeOverflow){
this.value=this.max;
}
//不允许前导零
而(this.value.length>1&&this.value.toString()[0]=“0”){
this.value=this.value.toString().slice(1);
}
});
inputBox.addEventListener(“向下键”,函数(e){
//不允许使用浮点数(如果不是预期的)
如果(!isFloat(此步骤)){
如果(e.key==”){
e、 预防默认值();
}
}
},假);
函数更改(){
inputBox.value=“005”;
dispatchEvent(新事件('input'));
}
函数isFloat(n){
返回编号(n)==n&&n%1!==0;
}


change
您可以为
inputBox.value定义setter,这样它就可以调用您的函数。@IvanShmidt您能提供一个工作示例吗?“也许是?”伊凡希米德我觉得这没用。这只允许编程输入。如果通过UI在字段中输入数字,则无法使用
inputBox.value
获取输入的值,因为重新定义
属性会破坏输入字段的行为。-可编程和通过UISE查看问题底部的注释。不确定“用户以编程方式输入”是什么意思,但是,您可以使用setInterval()在定期间隔验证字段的值。
isFloat()
函数,或者更确切地说,期望
n
是一个数字。不能直接使用输入值(字符串)验证输入值。看这个。但是,它为多种情况做好了准备。“用户以编程方式输入”意味着可以打开控制台并更改其中的值以绕过验证。
inputBox.addEventListener("input", function () {
    validateInput(this);
});

inputBox.addEventListener("keydown", function (e) {
    validateInput(this, e);
});

function validateInput(elm, e) {
    // handle keydown event
    if (e) {
        // do not allow floating-point numbers, if it's not expected
        if (!isFloat(elm.step)) {
            if (e.key == ".") {
                e.preventDefault();
            }
        }
    }
    // handle input event
    else {
        // do not allow leading zeros
        while (elm.value.length > 1 && elm.value[0] === "0") {
            elm.value = elm.value.toString().slice(1);
        }
        // input should be between min and max
        if (elm.validity.rangeUnderflow) {
            elm.value = elm.min;
        }
        else if (elm.validity.rangeOverflow) {
            elm.value = elm.max;
        }
    }
}