当 <input>
时发生了什么事件?元素的值是通过 JavaScript 代码更改的吗?例如:
$input.value = 12;
input
事件在这里没有帮助,因为改变值的不是用户。
在 Chrome 上测试时,change
事件没有被触发。也许是因为元素没有失去焦点(它没有获得焦点,所以它不能失去它)?
最佳答案
没有内置事件。您至少有四种选择:
- 任何时候你改变代码中的
$input.value
,调用你想要由改变触发的代码 - 轮询更改
- 给自己一个用于更改值的方法,该方法也会发出通知
- (#3 的变体)给自己一个属性,您可以使用它来更改值,它也会发出通知
其中,您会注意到 #1、#3 和 #4 都要求您在代码中做一些不同于 $input.value = "new value";
轮询的事情,选项 #2,是唯一可以使用直接设置 value
的代码的选项。
详细信息:
最简单的解决方案:每当您在代码中更改
$input.value
时,调用您希望由更改触发的代码:$input.value = "new value"; handleValueChange();
轮询更改:
var last$inputValue = $input.value; setInterval(function() { var newValue = $input.value; if (last$inputValue != newValue) { last$inputValue = newValue; handleValueChange(); } }, 50); // 20 times/second
轮询的名声不好(有充分的理由),因为它经常消耗 CPU。当标签没有焦点时,现代浏览器调用了计时器事件(甚至将它们停止),这有点减轻。 20 次/秒在现代系统甚至手机上都不是问题。
但是,轮询仍然是一个丑陋的最后手段。
例子:
var $input = document.getElementById("$input"); var last$inputValue = $input.value; setInterval(function() { var newValue = $input.value; if (last$inputValue != newValue) { last$inputValue = newValue; handleValueChange(); } }, 50); // 20 times/second function handleValueChange() { console.log("$input's value changed: " + $input.value); } // Trigger a change setTimeout(function() { $input.value = "new value"; }, 800);
<input type="text" id="$input">
给自己一个函数来设置值并通知您,并使用该函数代替
value
,结合input
事件处理程序以捕获更改用户:$input.setValue = function(newValue) { this.value = newValue; handleValueChange(); }; $input.addEventListener("input", handleValueChange, false);
用法:
$input.setValue("new value");
当然,您必须记住使用
setValue
而不是分配给value
。例子:
var $input = document.getElementById("$input"); $input.setValue = function(newValue) { this.value = newValue; handleValueChange(); }; $input.addEventListener("input", handleValueChange, false); function handleValueChange() { console.log("$input's value changed: " + $input.value); } // Trigger a change setTimeout(function() { $input.setValue("new value"); }, 800);
<input type="text" id="$input">
#3 的一个变体:给自己一个可以设置的不同属性(再次结合用户更改的事件处理程序):
Object.defineProperty($input, "val", { get: function() { return this.value; }, set: function(newValue) { this.value = newValue; handleValueChange(); } }); $input.addEventListener("input", handleValueChange, false);
用法:
$input.val = "new value";
这适用于所有现代浏览器,甚至是旧的 Android,甚至是 IE8(它支持 DOM 元素上的
defineProperty
,但通常不支持 JavaScript 对象)。当然,您需要在目标浏览器上对其进行测试。但是对于习惯阅读普通 DOM 代码(或 jQuery 代码)的人来说,
$input.val = ...
看起来像是一个错误。在你问之前:不,你不能使用上面的来替换
value
属性本身。例子:
var $input = document.getElementById("$input"); Object.defineProperty($input, "val", { get: function() { return this.value; }, set: function(newValue) { this.value = newValue; handleValueChange(); } }); $input.addEventListener("input", handleValueChange, false); function handleValueChange() { console.log("$input's value changed: " + $input.value); } // Trigger a change setTimeout(function() { $input.val = "new value"; }, 800);
<input type="text" id="$input">
关于javascript - JavaScript 更改输入值时的事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42427606/