JavaScript更改输入值时发生的事件?
当通过JavaScript代码更改JavaScript更改输入值时发生的事件?,javascript,events,Javascript,Events,当通过JavaScript代码更改元素的值时,会发生什么事件?例如: $input.value = 12; input事件在这里没有帮助,因为更改值的不是用户 在Chrome上测试时,不会触发change事件。可能是因为元素没有失去焦点(它没有获得焦点,所以它不能失去焦点)?一种可能的策略是使用a来检测属性中的更改,如下所示: var observer = new MutationObserver(function(mutations) { mutations.forEac
元素的值时,会发生什么事件?例如:
$input.value = 12;
input
事件在这里没有帮助,因为更改值的不是用户
在Chrome上测试时,不会触发
change
事件。可能是因为元素没有失去焦点(它没有获得焦点,所以它不能失去焦点)?一种可能的策略是使用a来检测属性中的更改,如下所示:
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(){
console.log('hello')});
});
observer.observe($input, {
attributes: true
});
尽管这本身不会检测到以下变化:
$input.value = 12
它将检测实际值属性的变化:
$input.setAttribute('value', 12)
因此,如果是您以编程方式设置值,只需确保更改
value=12
语句旁边的属性,就可以得到所需的结果。我不认为有一个事件会覆盖输入的所有编程指定场景。但是,我可以告诉您,您可以通过编程“触发”事件(自定义事件、常规事件或仅触发事件处理程序)
在我看来,您正在使用jQuery,因此,您可以使用:
$('input#inputId').val('my new value...').triggerHandler('change');
在该示例中,您正在分配一个值,并强制调用绑定了“change”事件的处理程序。没有用于该事件的内置事件。您至少有四种选择:
$input.value
,都可以调用更改所触发的代码$input.value=“new value”不同的操作代码>轮询选项#2是唯一可以直接设置值的代码
详情:
最简单的解决方案是:在代码中更改$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(函数(){
var newValue=$input.value;
如果(最后$inputValue!=新值){
最后$inputValue=新值;
handleValueChange();
}
}, 50); // 20次/秒
函数handleValueChange(){
log(“$input的值已更改:”+$input.value);
}
//触发变化
setTimeout(函数(){
$input.value=“新值”;
}, 800);代码>
我会根据T.J.Crowder的建议添加第五个选项。
但是,不必添加新属性,您可以更改实际的“value”属性,以便在设置时触发额外的操作-对于特定的输入元素或所有输入对象:
//First store the initial descriptor of the "value" property:
var descriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value");
var inputSetter = descriptor.set;
//Then modify the "setter" of the value to notify when the value is changed:
descriptor.set = function(val) {
//changing to native setter to prevent the loop while setting the value
Object.defineProperty(this, "value", {set:inputSetter});
this.value = val;
//Custom code triggered when $input.value is set
console.log("Value set: "+val);
//changing back to custom setter
Object.defineProperty(this, "value", descriptor);
}
//Last add the new "value" descriptor to the $input element
Object.defineProperty($input, "value", descriptor);
可以对所有输入元素进行常规更改,而不是更改特定输入元素的“value”属性:
Object.defineProperty(HTMLInputElement.prototype, "value", descriptor);
此方法仅适用于使用javascript更改值,例如input.value=“new value”。在输入框中键入新值时,它不起作用。基于@t-j-crowder和@maciej swist answers,让我们添加这一个,使用“.apply”函数防止无限循环而不重新定义对象
function customInputSetter(){
var descriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value");
var originalSet = descriptor.set;
// define our own setter
descriptor.set = function(val) {
console.log("Value set", this, val);
originalSet.apply(this,arguments);
}
Object.defineProperty(HTMLInputElement.prototype, "value", descriptor);
}
下面是一个钩住所有输入的值属性更改的解决方案:
var valueDescriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value");
HTMLInputElement.prototype.addInputChangedByJsListener = function(cb) {
if(!this.hasOwnProperty("_inputChangedByJSListeners")) {
this._inputChangedByJSListeners = [];
}
this._inputChangedByJSListeners.push(cb);
}
Object.defineProperty(HTMLInputElement.prototype, "value", {
get: function() {
return valueDescriptor.get.apply(this, arguments);
},
set: function() {
var self = this;
valueDescriptor.set.apply(self, arguments);
if(this.hasOwnProperty("_inputChangedByJSListeners")){
this._inputChangedByJSListeners.forEach(function(cb) {
cb.apply(self);
})
}
}
});
用法示例:
document.getElementById("myInput").addInputChangedByJsListener(function() {
console.log("Input changed to \"" + this.value + "\"");
});
一种简单的方法就是在更改值时触发输入事件
您可以用普通javascript实现这一点
在脚本的早期,将以下内容放在脚本中:
let inputEvent = new Event('input',{bubbles:true,cancelable: true});
您可以将“输入”更改为所需的事件,“更改”、“模糊”等
然后,无论何时更改值,只要在同一元素上调用此事件即可
input.value = 12;// <- your example
input.dispatchEvent(inputEvent);// <- calling an event
input.value=12;//当值被Javascript更改时没有事件。@Kinduser否…虽然存在一些异常,但事件大多是由于影响浏览器的外部操作而触发的,而不是来自Javascript代码。@Kinduser“否”是完整答案。我似乎找不到非jQuery副本,例如这是一个非常奇特的解决方案。实际上我需要反映外部的变化,这样才不会帮助我。但这仍然是一个很好的解决方案,它在chrome和firefox上都能运行。它们似乎也改变了dom中的值!聪明和有黑客感,我喜欢它,只是确保在调试时只使用它:)所有的要点是第三方更改了值不是我,而是谢谢你的建议