<input type="text">
罐的价值有多种变化方式,包括:
- 按键
- 复制粘贴
- 用JavaScript修改
- 通过浏览器或工具栏自动完成
我希望我的JavaScript函数在每次更改时都被调用(使用当前输入值)。我希望立即调用它,而不仅仅是输入失去焦点时。
我正在寻找最干净,最可靠的方法来在所有浏览器中执行此操作(最好使用jQuery)。
<input type="text">
罐的价值有多种变化方式,包括:
我希望我的JavaScript函数在每次更改时都被调用(使用当前输入值)。我希望立即调用它,而不仅仅是输入失去焦点时。
我正在寻找最干净,最可靠的方法来在所有浏览器中执行此操作(最好使用jQuery)。
Answers:
此jQuery代码可捕获对任何元素的立即更改,并且应可在所有浏览器上使用:
$('.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
....
}
});
});
document.getElementById('txtInput').value = 'some text';
input
事件参考指出,通过JavaScript修改内容时不会触发。但是,该事件确实会通过JS进行修改(请参见此处)。因此,当通过IE上的JS修改内容时,此代码将起作用,但在其他浏览器上将不起作用。onpropertychange
jQuery> = 1.9的实时花式解决方案
$("#input-id").on("change keyup paste", function(){
dosomething();
})
如果您还想检测“点击”事件,只需:
$("#input-id").on("change keyup paste click", function(){
dosomething();
})
如果您使用的是jQuery <= 1.4,请使用live
代替on
。
不幸的是,我认为setInterval
获奖:
<input type=text id=input_id />
<script>
setInterval(function() { ObserveInputValue($('#input_id').val()); }, 100);
</script>
这是最干净的解决方案,只需一行代码。它也是最强大的,因为您不必担心所有不同的事件/方式input
都可以获取价值。
在这种情况下,使用'setInterval'的缺点似乎并不适用:
绑定到oninput
事件似乎在大多数理智的浏览器中都可以正常工作。IE9也支持它,但是实现存在错误(删除字符时不会触发该事件)。
使用jQuery 1.7+版本时,该on
方法可用于绑定到如下事件:
$(".inputElement").on("input", null, null, callbackFunction);
不幸的是,没有符合您条件的事件或事件集。按键和复制/粘贴都可以与该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在评论中指出的那样,如果您需要观察大量输入,则此解决方案可能无法很好地扩展。您始终可以将2nd参数调整为setInterval()
或多或少地进行检查。
myTextBox.value = 'foo';
无JavaScript事件处理这种情况。
input.onpropertychange
,FF2 +,Opera 9.5,Safari 3和Chrome 1来处理它input.__defineSetter__('value', ...)
(尽管据证明在DOM节点上不能正常工作,但我可以验证有用)。与IE实现的唯一区别是IE不仅在编程设置上而且在关键事件期间都触发处理程序。
如果您不喜欢其他任何答案,则这里的解决方案略有不同:
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() {
将此代码添加到某处,即可解决问题。
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;
};
在val()发现此解决方案不会触发jQuery中的change()
我创建了一个样本。愿它为您服务。
var typingTimer;
var doneTypingInterval = 10;
var finaldoneTypingInterval = 500;
var oldData = $("p.content").html();
$('#tyingBox').keydown(function () {
clearTimeout(typingTimer);
if ($('#tyingBox').val) {
typingTimer = setTimeout(function () {
$("p.content").html('Typing...');
}, doneTypingInterval);
}
});
$('#tyingBox').keyup(function () {
clearTimeout(typingTimer);
typingTimer = setTimeout(function () {
$("p.content").html(oldData);
}, finaldoneTypingInterval);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<textarea id="tyingBox" tabindex="1" placeholder="Enter Message"></textarea>
<p class="content">Text will be replace here and after Stop typing it will get back</p>
实际上,我们不需要设置循环来检测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更改时,此功能才可用。
好吧,最好的方法是覆盖您自己列出的这三个基础。简单的:onblur,:onkeyup等无法满足您的需求,因此只需将它们组合即可。
KeyUp应该涵盖前两个,如果Javascript修改了输入框,那么我当然希望它是您自己的javascript,因此只需在修改它的函数中添加一个回调即可。
这是一个工作示例,我正在使用它来实现自动完成变体,它会填充一个jqueryui选择器(列表),但我不希望它的功能与执行下拉菜单的jqueryui自动完成功能完全相同。
$("#tagFilter").on("change keyup paste", function() {
var filterText = $("#tagFilter").val();
$("#tags").empty();
$.getJSON("http://localhost/cgi-bin/tags.php?term=" + filterText,
function(data) {
var i;
for (i = 0; i < data.length; i++) {
var tag = data[i].value;
$("#tags").append("<li class=\"tag\">" + tag + "</li>");
}
});
});
没有JQUERY!(无论如何,这几天过时了)
编辑:我删除了HTML事件。不要使用HTML事件...而是使用Javascript事件监听器。
document.querySelector("#testInput").addEventListener("input", test);
function test(e) {
var a = document.getElementById('output');
var b = /^[ -~]+$/;
if (e.target.value == '' || b.test(e.target.value)) {
a.innerText = "Text is Ascii?.. Yes";
} else if (!b.test(e.target.value)) {
a.innerText = "Text is Ascii?.. No";
}
}
Try pressing Alt+NumPad2+NumPad3 in the input, it will instantly detect a change, whether you Paste, Type, or any other means, rather than waiting for you to unselect the textbox for changes to detect.
<input id="testInput">
<br>
<a id="output">Text is Ascii?.. Yes</a>
您不能只使用<span contenteditable="true" spellcheck="false">
element代替<input type="text">
吗?
<span>
(具有contenteditable="true" spellcheck="false"
as属性)的区别<input>
主要在于:
<input>
。value
属性,但是文本被渲染为文本innerText
并成为其内部主体的一部分。 <input>
尽管您设置了属性,但不是multiline="true"
。当然,要完成外观,您可以在CSS中设置其样式,而将值写为 innerText
获得一个事件:
这是一个小提琴。
不幸的是,有些东西在IE和Edge中实际上不起作用,而我找不到。
尽管这个问题是10年前发布的,但我认为它仍然需要一些改进。所以这是我的解决方案。
$(document).on('propertychange change click keyup input paste', 'selector', function (e) {
// Do something here
});
此解决方案的唯一问题是,如果值从javascript更改为,它不会触发$('selector').val('some value')
。当您更改javascript的值时,可以向选择器触发任何事件。
$(selector).val('some value');
// fire event
$(selector).trigger('change');
您可以看到此示例并选择您感兴趣的事件:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<title>evetns</title>
</head>
<body>
<form>
<input class="controlevents" id="i1" type="text" /><br />
<input class="controlevents" id="i2" type="text" /><br />
<input class="controlevents" id="i3" type="text" /><br />
<input class="controlevents" id="i4" type="text" /><br />
<input class="controlevents" id="i5" type="text" /><br />
</form>
<div id="datatext"></div>
</body>
</html>
<script>
$(function(){
function testingevent(ev){
if (ev.currentTarget.tagName=="INPUT")
$("#datatext").append("<div>id : " + ev.currentTarget.id + ", tag: " + ev.currentTarget.tagName + ", type: "+ ev.type +"</div>");
}
var eventlist = ["resizeend","rowenter","dragleave","beforepaste","dragover","beforecopy","page","beforeactivate","beforeeditfocus","controlselect","blur",
"beforedeactivate","keydown","dragstart","scroll","propertychange","dragenter","rowsinserted","mouseup","contextmenu","beforeupdate",
"readystatechange","mouseenter","resize","copy","selectstart","move","dragend","rowexit","activate","focus","focusin","mouseover","cut",
"mousemove","focusout","filterchange","drop","blclick","rowsdelete","keypress","losecapture","deactivate","datasetchanged","dataavailable",
"afterupdate","mousewheel","keyup","movestart","mouseout","moveend","cellchange","layoutcomplete","help","errorupdate","mousedown","paste",
"mouseleave","click","drag","resizestart","datasetcomplete","beforecut","change","error","abort","load","select"];
var inputs = $(".controlevents");
$.each(eventlist, function(i, el){
inputs.bind(el, testingevent);
});
});
</script>
我可能在这里参加聚会很晚,但是您不能只使用jQuery提供的.change()事件。
您应该能够执行类似...
$(#CONTROLID).change(function(){
do your stuff here ...
});
您可以始终将其绑定到控件列表,例如...
var flds = $("input, textarea", window.document);
flds.live('change keyup', function() {
do your code here ...
});
活页夹确保当前和将来存在于页面上的所有元素都得到处理。
这是最快,最干净的方法:
我正在使用Jquery->
$('selector').on('change', function () {
console.log(this.id+": "+ this.value);
});
对我来说一切正常。