问题描述

有多种方式,< input type = “text”> 可以改变,包括:

  • 按键

  • 复制粘贴

  • 用 JavaScript 修改

  • auto-completed 通过浏览器或工具栏

我希望我的 JavaScript 函数随时更改 (当前的输入值) 被调用。而且我希望它立即被打来,而不仅仅是当输入失去焦点时。

我正在寻找在所有浏览器 (最好使用 jQuery) 这样做最干净,最强大的方法。

示例用例:在 Twitter Signup 页面上,用户名字段的值显示在其下面的 URL「http://twitter/ username」 中。

最佳解决方案

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

次佳解决方案

不幸的是,我认为 setInterval 获奖:

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

这是最简单的解决方案,只有一行代码。它也是最强大的,因为您不必担心 input 可以获得的所有不同的事件/方式。

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

  • 100ms 延迟?对于许多应用,100ms 足够快。

  • 在浏览器上增加了负载?一般来说,在您的页面上添加大量 heavy-weight setIntervals 是不好的。但在这种特殊情况下,增加的页面加载是不可检测的。

  • 它不会扩展到许多输入?大多数页面没有多少输入,您可以在同一个 setInterval 中嗅探所有的输入。

第三种解决方案

jquery 的实时花式解决方案> = 1.9

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

如果还要检测”click” 事件,只需:

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

如果你的 jquery <= 1.4,只需使用"live" 而不是"on" 。

第四种方案

绑定到 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()将’watch’ 更改为文本框:

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

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

第六种方案

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

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

考虑到您无法依靠点击和密钥来捕获上下文菜单粘贴。

第七种方案

我创建了一个示例。可能会为你工作

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://googleajax.admincdn.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/

第八种方案

2017 答案:input event 完全符合 IE8 的要求。

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

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛