检测输入类型文本的编程更改

Zo7*_*o72 26 html javascript

有什么方法可以在脚本更改输入类型文本的值时获得通知.

我有

<input id='test' type='text' />
Run Code Online (Sandbox Code Playgroud)

和一个脚本

document.getElementById('test').value = 'bbb'; 
Run Code Online (Sandbox Code Playgroud)

我希望收到有关文本更改的通知.

我知道我可以通过keydown,keyup,onblur etcetera通知(如果我试图跟踪用户输入,它可以工作)但是如果更改是以编程方式完成的呢?

非常感谢

ps没有JQuery请或如果jquery这样做,有人可以解释它是如何实现它的.

Max*_*Art 17

如果您正在处理现代浏览器,可以试试这样的事情:

var input = document.getElementById('test');
input._value = input.value;
Object.defineProperty(input, "value", {
    get: function() {return this._value;},
    set: function(v) {
        // Do your stuff
        this._value = v;
    }
});
Run Code Online (Sandbox Code Playgroud)

如果您实际上不期望任何用户输入(即隐藏类型输入字段),则此解决方案很好,因为它极大地破坏了DOM基本功能.记在脑子里.

  • 似乎当您重新定义“值”属性时,输入字段不再“连接”到“值”属性。 (2认同)
  • @MaxArt这真的很聪明......但是有没有副作用?我有点担心重新定义'价值'属性 (2认同)

Fél*_*ier 15

我发现最简单的方法是手动触发事件:

document.getElementById('test').value = 'bbb';
var evt = new CustomEvent('change');
document.getElementById('test').dispatchEvent(evt);
Run Code Online (Sandbox Code Playgroud)

change当以编程方式更改值时,只是倾听事件是容易出错的.但是,由于您要更改值,因此添加两行并使用CustomEvent触发change事件.

那么你将能够捕获这个change事件,内联:

<input id="test" onchange="console.log(this)">
Run Code Online (Sandbox Code Playgroud)

或与听众:

document.getElementById('test').addEventListener('change',function(event) {
    console.log(event.target);
});
Run Code Online (Sandbox Code Playgroud)

这样做的好处是,如果您有一个可以由用户更改的输入,您可以捕获这些事件(来自用户或脚本)

然而,这取决于您自己以编程方式更改输入的值.如果您正在使用更改输入值的库(例如datepickr),则可能需要输入代码并在正确的位置添加这两行.

  • 问题是,当您想要检测代码中的值更改时**您不是**的作者,因此您不能在值更改时简单地触发假事件,而必须以某种方式“检测”它。(我有一个第三方插件需要检测这样的事情) (3认同)

Kai*_*ido 7

MaxArt 解决方案的破坏性较小的版本是随后调用实际的 HTMLInputElement 的 setter 和 getter:

const input = document.querySelector("input");
const desc = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value");
Object.defineProperty(input, "value", {
    get: desc.get,
    set: function(v) {
        console.log("setting programmatically", v);
        desc.set.call(this, v);
    }
});

input.value = "This is correctly set everywhere";
const fd = new FormData(input.parentNode);
console.log("It gets sent as part of the form", ...fd);

input.oninput = (evt) => {
  console.log("user inputs still do work");
};
Run Code Online (Sandbox Code Playgroud)
<form>
  <input name=inp>
</form>
Run Code Online (Sandbox Code Playgroud)