一个 <input type="text">
元素的值可以通过多种方式改变,包括:
- 按键事件
- 复制/粘贴
- 使用 JavaScript 修改
- 由浏览器或工具栏自动完成
我希望在输入框的内容发生变化时,立即调用我的 JavaScript 函数(并传递当前输入框的值),而不仅是在输入框失去焦点时调用。
我正在寻找最干净、最健壮的跨所有浏览器的方法(最好使用 jQuery)。
一个 <input type="text">
元素的值可以通过多种方式改变,包括:
我希望在输入框的内容发生变化时,立即调用我的 JavaScript 函数(并传递当前输入框的值),而不仅是在输入框失去焦点时调用。
我正在寻找最干净、最健壮的跨所有浏览器的方法(最好使用 jQuery)。
这段 jQuery 代码使用 .bind()
捕获任何元素的即时更改,并应该适用于所有浏览器:
$('.myElements').each(function() {
var elem = $(this);
// Save current value of element
elem.data('oldVal', elem.val());
// Look for changes in the value
elem.bind("propertychange change click keyup input paste", function(event){
// If value has changed...
if (elem.data('oldVal') != elem.val()) {
// Updated stored value
elem.data('oldVal', elem.val());
// Do action
....
}
});
});
不过请注意,.bind()
在jQuery 3.0版本中已被弃用。任何使用jQuery 1.7或更高版本的人应该改用.on()
。
input
是HTML5事件,我认为应该覆盖所有现代浏览器(MDN参考文档)。 keyup
应该可以捕获其余事件,但存在轻微延迟(input
由按键按下时触发)。 propertychange
是专有的微软事件,我不确定是否实际上需要使用paste
。 - Jo Lissdocument.getElementById('txtInput').value = 'some text';
。 - Mehmet Ataş很遗憾,我认为setInterval
是最佳选择:
<input type=text id=input_id />
<script>
setInterval(function() { ObserveInputValue($('#input_id').val()); }, 100);
</script>
这是最简单的解决方案,只需1行代码。它也是最健壮的,因为您无需担心所有不同的事件/方式input
可以获得值。
使用“setInterval”的缺点似乎不适用于此情况:
input
事件在大多数正常的浏览器中运行良好。IE9也支持,但实现存在缺陷(删除字符时不会触发事件)。on
方法非常有用,可以这样绑定事件:$(".inputElement").on("input", null, null, callbackFunction);
oninput
事件无法与input[type=reset]
或JavaScript编辑一起使用。 - Yukulélé很遗憾,没有事件或一组事件与您的条件相匹配。键盘按键和复制/粘贴可以通过keyup
事件处理。使用JS进行更改要困难得多。如果您控制设置文本框的代码,则最好修改它以直接调用您的函数或在文本框上触发用户事件:
// Compare the textbox's current and last value. Report a change to the console.
function watchTextbox() {
var txtInput = $('#txtInput');
var lastValue = txtInput.data('lastValue');
var currentValue = txtInput.val();
if (lastValue != currentValue) {
console.log('Value changed from ' + lastValue + ' to ' + currentValue);
txtInput.data('lastValue', currentValue);
}
}
// Record the initial value of the textbox.
$('#txtInput').data('lastValue', $('#txtInput').val());
// Bind to the keypress and user-defined set event.
$('#txtInput').bind('keypress set', null, watchTextbox);
// Example of JS code triggering the user event
$('#btnSetText').click(function (ev) {
$('#txtInput').val('abc def').trigger('set');
});
如果您无法控制该代码,可以使用setInterval()
来“监视”文本框的更改:
// Check the textbox every 100 milliseconds. This seems to be pretty responsive.
setInterval(watchTextbox, 100);
这种主动监控不会“立即”捕捉到更新,但它似乎足够快,没有察觉到的延迟。正如DrLouie在评论中指出的那样,如果您需要监视大量输入,则该解决方案可能无法很好地扩展。您始终可以调整setInterval()
的第二个参数来更或少频繁地检查。
input.onpropertychange
处理它,而FF2+、Opera 9.5、Safari 3和Chrome 1可以使用input.__defineSetter__('value', ...)
处理它(虽然它被记录为在DOM节点上不起作用,但我可以验证它有效)。唯一与IE实现不同的是IE不仅在编程设置时而且在键事件期间也触发处理程序。 - Crescent FreshsetInterval
有点像最后的手段。因此,如果您可以修改更新文本框的JS代码,我添加了一个可供使用的替代解决方案。 - Annabelledocument.querySelector("#testInput").addEventListener("input", test);
function test(e) {
var a = document.getElementById('output');
a.innerText += "Detected an Update!\n";
}
<input id="testInput">
<br>
<a id="output"></a>
如果你不喜欢其他答案,这里有一个稍微不同的解决方案:
var field_selectors = ["#a", "#b"];
setInterval(function() {
$.each(field_selectors, function() {
var input = $(this);
var old = input.attr("data-old-value");
var current = input.val();
if (old !== current) {
if (typeof old != 'undefined') {
... your code ...
}
input.attr("data-old-value", current);
}
}
}, 500);
$("input[id^=Units_]").each(function() {
- robr在任意位置添加以下代码,这将解决问题。
var originalVal = $.fn.val;
$.fn.val = function(){
var result =originalVal.apply(this,arguments);
if(arguments.length>0)
$(this).change(); // OR with custom event $(this).trigger('value-changed');
return result;
};
实际上,我们不需要设置循环来检测JavaScript的更改。我们已经为要检测的元素设置了许多事件侦听器。只需要触发任何无害的事件就可以完成工作。
$("input[name='test-element']").on("propertychange change click keyup input paste blur", function(){
console.log("yeh thats worked!");
});
$("input[name='test-element']").val("test").trigger("blur");
当然,只有在您完全控制项目中的JavaScript更改时才能使用此功能。
虽然这个问题已经发布了10年,但我认为仍需要一些改进。因此,以下是我的解决方案。
$(document).on('propertychange change click keyup input paste', 'selector', function (e) {
// Do something here
});
$('selector').val('some value')
,它就不会触发。您可以在从JavaScript更改值时对选择器触发任何事件。$(selector).val('some value');
// fire event
$(selector).trigger('change');
或者在一行中
$(selector).val('some value').trigger('change');