Detect all changes to a (immediately) using JQuery
- 按键
- 复制粘贴
- 用JavaScript修改
- 通过浏览器或工具栏自动完成
我希望我的JavaScript函数在任何时候都会被调用(使用当前输入值)。 我希望它能立即被调用,而不仅仅是当输入失去焦点时。
我正在寻找在所有浏览器中执行此操作的最干净,最强大的方法(最好使用jQuery)。
示例用例:在Twitter注册页面上,用户名字段的值显示在其下方的URL"http:// twitter / username"中。
这个jQuery代码捕获任何元素的即时更改,并且应该适用于所有浏览器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | $('.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 .... } }); }); |
jQuery> = 1.9的实时奇特解决方案
1 2 3 | $("#input-id").on("change keyup paste", function(){ dosomething(); }) |
如果您还想检测"点击"事件,只需:
1 2 3 | $("#input-id").on("change keyup paste click", function(){ dosomething(); }) |
如果你使用jQuery <= 1.4,只需使用
不幸的是,我认为
1 2 3 | <input type=text id=input_id /> setInterval(function() { ObserveInputValue($('#input_id').val()); }, 100); |
这是最干净的解决方案,只有一行代码。它也是最强大的,因为您不必担心
在这种情况下,使用'setInterval'的缺点似乎不适用:
- 100毫秒的延迟?对于许多应用,100ms足够快。
- 在浏览器上添加了负载?通常,在页面上添加大量的重量级setIntervals是不好的。但在这种特殊情况下,添加的页面加载是不可检测的。
- 它不能扩展到许多输入?大多数页面没有多少输入,您可以在同一个setInterval中嗅探所有输入。
绑定到
使用jQuery 1.7+版本,
1 | $(".inputElement").on("input", null, null, callbackFunction); |
2017答案:输入事件对IE8的最新版本确实如此。
1 | $(el).on('input', callback) |
遗憾的是,没有符合您条件的事件或事件集。可以使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | // 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'); }); |
如果您无法控制该代码,可以使用
1 2 | // Check the textbox every 100 milliseconds. This seems to be pretty responsive. setInterval(watchTextbox, 100); |
这种主动监控不会立即捕获更新,但似乎足够快,没有明显的滞后。正如DrLouie在评论中指出的那样,如果你需要观察大量的输入,这个解决方案可能无法很好地扩展。您始终可以将第二个参数调整为
如果你不喜欢任何其他答案,这里有一个稍微不同的解决方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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); |
考虑到您不能依靠点击和键盘来捕获上下文菜单粘贴。
在某个地方添加此代码,这将解决问题。
1 2 3 4 5 6 7 | 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()
我创建了一个样本。愿它适合你。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | 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"> <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> |
http://jsfiddle.net/utbh575s/
实际上,我们不需要设置循环来检测javaScript更改。
我们已经为要检测的元素设置了许多事件监听器。只是触发任何无害的事件都会成功。
1 2 3 4 5 | $("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更改有完全控制权时才能使用此功能。
这是一个工作示例,我用来实现自动完成变体,填充jqueryui选择器(列表),但我不希望它的功能完全像jqueryui自动完成,它执行下拉菜单。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | $("#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> "); } }); }); |
那么,最好的办法是覆盖你自己列出的三个基地。一个简单的:onblur,:onkeyup等不适用于你想要的东西,所以只需将它们组合起来。
KeyUp应该涵盖前两个,如果Javascript正在修改输入框,我确定希望它是你自己的javascript,所以只需在修改它的函数中添加一个回调。
你不能只用
-
它的风格不像
。 -
它没有
value 属性,但文本呈现为innerText 并成为其内部主体的一部分。 -
它是多行,而
不是你设置属性 multiline="true" 。
为了实现外观,您当然可以在CSS中设置样式,而将值写为
这是一个小提琴。
不幸的是,有些东西在IE和Edge中实际上没有用,我无法找到。
您可以看到此示例并选择您感兴趣的事件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | <!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"> evetns </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> </body> </html> $(function(){ function testingevent(ev){ if (ev.currentTarget.tagName=="INPUT") $("#datatext").append("id :" + ev.currentTarget.id +", tag:" + ev.currentTarget.tagName +", type:"+ ev.type +""); } 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); }); }); |
我可能在这里参加聚会,但你不能只使用jQuery提供的.change()事件。
你应该可以做类似......
1 2 3 | $(#CONTROLID).change(function(){ do your stuff here ... }); |
你总是可以将它绑定到一个控件列表,例如...
1 2 3 4 5 | var flds = $("input, textarea", window.document); flds.live('change keyup', function() { do your code here ... }); |
实时绑定器可确保处理现在和将来页面上存在的所有元素。
这是最快速,最干净的方法:
我正在使用Jquery - >
1 2 3 | $('selector').on('change', function () { console.log(this.id+":"+ this.value); }); |
它对我来说很好。