Javascript 使用 JQuery 检测对 <input type="text">(立即)的所有更改

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1948332/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 22:01:46  来源:igfitidea点击:

Detect all changes to a <input type="text"> (immediately) using JQuery

javascriptjqueryhtml

提问by Dustin Boswell

There are many ways the value of a <input type="text">can change, including:

a 的值<input type="text">可以通过多种方式改变,包括:

  • keypresses
  • copy/paste
  • modified with JavaScript
  • auto-completed by browser or a toolbar
  • 按键
  • 复制粘贴
  • 用 JavaScript 修改
  • 由浏览器或工具栏自动完成

I want my JavaScript function to be called (with the current input value) any time it changes. And I want it to be called right away, not just when the input loses focus.

我希望我的 JavaScript 函数在它发生变化时被调用(使用当前输入值)。而且我希望它立即被调用,而不仅仅是在输入失去焦点时。

I'm looking for the cleanest and most robust way to do this across all browsers (using jQuery preferably).

我正在寻找在所有浏览器中执行此操作的最干净和最健壮的方法(最好使用 jQuery)。

采纳答案by Dustin Boswell

Unfortunately, I think setIntervalwins the prize:

不幸的是,我认为setInterval得奖了:

<input type=text id=input_id />
<script>
setInterval(function() { ObserveInputValue($('#input_id').val()); }, 100);
</script>

It's the cleanest solution, at only 1 line of code. It's also the most robust, since you don't have to worry about all the different events/ways an inputcan get a value.

这是最干净的解决方案,只有 1 行代码。它也是最健壮的,因为您不必担心input可以获得值的所有不同事件/方式。

The downsides of using 'setInterval' don't seem to apply in this case:

在这种情况下,使用“setInterval”的缺点似乎并不适用:

  • The 100ms latency?For many applications, 100ms is fast enough.
  • Added load on the browser?In general, adding lots of heavy-weight setIntervals on your page is bad. But in this particular case, the added page load is undetectable.
  • It doesn't scale to many inputs?Most pages don't have more than a handful of inputs, which you can sniff all in the same setInterval.
  • 100 毫秒的延迟?对于许多应用程序,100ms 已经足够快了。
  • 在浏览器上增加了负载?一般来说,在页面上添加大量重量级的 setIntervals 是不好的。但在这种特殊情况下,增加的页面加载是无法检测的。
  • 它不能扩展到许多输入?大多数页面只有少量输入,您可以在同一个 setInterval 中嗅探所有这些输入。

回答by phatmann

This jQuery code catches immediate changes to any element, and should work across all browsers:

此 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
       ....
     }
   });
 });

回答by Felix

A real-time fancy solution for jQuery >= 1.9

jQuery >= 1.9 的实时奇特解决方案

$("#input-id").on("change keyup paste", function(){
    dosomething();
})

if you also want to detect "click" event, just:

如果您还想检测“点击”事件,只需:

$("#input-id").on("change keyup paste click", function(){
    dosomething();
})

if you're using jQuery <= 1.4, just use liveinstead of on.

如果你正在使用jQuery <= 1.4,只需使用live代替on

回答by HRJ

Binding to the oninputevent seems to work fine in most sane browsers. IE9 supports it too, but the implementation is buggy (the event is not fired when deleting characters).

oninput在大多数理智的浏览器中绑定到事件似乎工作正常。IE9 也支持它,但实现有问题(删除字符时不会触发该事件)。

With jQuery version 1.7+ the onmethod is useful to bind to the event like this:

在 jQuery 1.7+ 版本中,该on方法对于绑定到这样的事件很有用:

$(".inputElement").on("input", null, null, callbackFunction);

回答by Chris F Carroll

2017 answer: the input eventdoes exactly this for anything more recent than IE8.

2017 年的回答输入事件对于比 IE8 更新的任何东西都这样做。

$(el).on('input', callback)

回答by Annabelle

Unfortunately there is no event or set of events that matches your criteria. Keypresses and copy/paste can both be handled with the keyupevent. Changes through JS are trickier. If you have control over the code that sets the textbox, your best bet is to modify it to either call your function directly or trigger a user event on the textbox:

不幸的是,没有符合您标准的事件或事件集。按键和复制/粘贴都可以通过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');
});

If you don't have control over that code, you could use setInterval()to 'watch' the textbox for changes:

如果您无法控制该代码,则可以使用setInterval()“观察”文本框进行更改:

// Check the textbox every 100 milliseconds.  This seems to be pretty responsive.
setInterval(watchTextbox, 100);

This sort of active monitoring won't catch updates 'immediately', but it seems to be fast enough that there is no perceptible lag. As DrLouie pointed out in comments, this solution probably doesn't scale well if you need to watch lots of inputs. You can always adjust the 2nd parameter to setInterval()to check more or less frequently.

这种主动监控不会“立即”捕获更新,但它似乎足够快,没有明显的滞后。正如 DrLouie 在评论中指出的那样,如果您需要观看大量输入,则此解决方案可能无法很好地扩展。您可以随时调整第二个参数以setInterval()增加或减少检查频率。

回答by Peder

Here is a slightly different solution if you didn't fancy any of the other answers:

如果您不喜欢任何其他答案,这里有一个稍微不同的解决方案:

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);

Consider that you cannot rely on click and keyup to capture context menu paste.

考虑到您不能依赖 click 和 keyup 来捕获上下文菜单粘贴。

回答by lpradhap

Add this code somewhere, this will do the trick.

将此代码添加到某处,即可解决问题。

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;
};

Found this solution at val() doesn't trigger change() in jQuery

val()处发现此解决方案不会触发 jQuery 中的 change()

回答by Ambuj Khanna

I have created a sample. May it will work for you.

我已经创建了一个示例。愿它对你有用。

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>

http://jsfiddle.net/utbh575s/

http://jsfiddle.net/utbh575s/

回答by Serdar

We actually don't need to setup loops for detecting javaScript changes. We already setting up many event listeners to the element we want to detect. just triggering any un harmful event will make the job.

我们实际上不需要设置循环来检测 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");

and ofc this is only available if you have the full control on javascript changes on your project.

并且只有当您完全控制项目中的 javascript 更改时,这才可用。