检测输入类型="text">(立即)使用JQuery

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

  • 按键
  • 复制/粘贴
  • JavaScript修改
  • 由浏览器或工具栏自动完成

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

我正在寻找最干净和最健壮的方法来跨所有浏览器(最好使用jQuery)。

453604 次浏览

不幸的是,没有事件或事件集符合您的标准。按键和复制/粘贴都可以用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(),以或多或少地检查。

好吧,最好的办法就是把你自己列出的三个基础都做一遍。一个简单的:onblur,:onkeyup等不会为你想要的工作,所以只是把它们结合起来。

KeyUp应该涵盖前两个,如果Javascript正在修改输入框,我当然希望它是你自己的Javascript,所以只需在修改它的函数中添加一个回调。

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

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

这是最简洁的解决方案,只有一行代码。它也是最健壮的,因为你不必担心input获取值的所有不同事件/方式。

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

  • 对于很多应用来说,100ms已经足够快了。
  • 增加了浏览器的负载?一般来说,在你的页面上添加大量的重量级setinterval是不好的。但在这种特殊情况下,无法检测到添加的页面负载。
  • 它不能扩展到很多输入?大多数页面的输入不超过几个,你可以在同一个setInterval中嗅探所有的输入。

这段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()

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

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

考虑到您不能依赖于单击和键up来捕获上下文菜单粘贴。

绑定到input事件似乎在大多数正常的浏览器中都能正常工作。IE9也支持它,但是实现有bug(删除字符时不会触发事件)。

在jQuery 1.7+版本中,on方法可以像这样绑定到事件:

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

jQuery >= 1.7的实时解决方案是on

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

如果你还想检测“点击”;事件,只是:

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

如果你正在使用jQuery <= 1.6,只需使用bindlive而不是on

我已经创建了一个样本。希望它对你有用。

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/

下面是一个工作示例,我使用它来实现一个填充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>");
}
});
});
我们实际上不需要设置循环来检测javaScript的变化。 我们已经为要检测的元素设置了许多事件监听器。只要触发任何UN有害事件就可以完成任务
$("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");

ofc只有在你对项目的javascript更改有完全控制的情况下才可用。

把这段代码添加到某个地方,就可以了。

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

在jQuery中val()不会触发change()找到这个解决方案

你不能用<span contenteditable="true" spellcheck="false">元素来代替<input type="text">吗?

<span>(带有contenteditable="true" spellcheck="false"作为属性)与<input>的区别主要在于:

  • 它的样式不像<input>
  • 它没有value属性,但文本被呈现为innerText并成为其内部主体的一部分。
  • 它是多行,而<input>不是,尽管你设置了属性multiline="true"

当然,要实现外观,你可以用CSS来设置它的样式,而将值写入innerText则可以为它获取一个事件:

这是一个小提琴

不幸的是,有一些东西在IE和Edge中实际上不起作用,我无法找到。

下面是一个不使用jQuery的解决方案(它真的很过时,现在没有必要了) < br >

使用事件"input",你可以查找任何类型的变化:

删除,后退,粘贴,输入,任何会改变输入值的东西。

input事件与文本输入直接相关。当文本以任何方式更改时,input将被分派。

document.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>

虽然这个问题是10年前发布的,但我认为它仍然需要改进。这就是我的解。

$(document).on('propertychange change click keyup input paste', 'selector', function (e) {
// Do something here
});

这个解决方案的唯一问题是,如果值从$('selector').val('some value')这样的javascript中改变,它不会触发。当你从javascript中改变值时,你可以触发任何事件到你的选择器。

$(selector).val('some value');
// fire event
$(selector).trigger('change');

或者排成一行

$(selector).val('some value').trigger('change');

您可以简单地识别表单中的所有更改者,如下所示

           //when form change, show aleart
$("#FormId").change(function () {
aleart('Done some change on form');
});

你可以将'input'事件绑定到<input type="text">。这将在每次输入更改(如复制、粘贴、按键等)时触发。

$("#input-id").on("input", function(){
// Your action
})