К сожалению, я думаю, что setInterval
выигрывает приз:
<input type=text id=input_id />
<script>
setInterval(function() { ObserveInputValue($('#input_id').val()); }, 100);
</script>
Это самое чистое решение, всего в 1 строке кода. Это также самое надежное решение, так как вам не нужно беспокоиться о различных событиях/способах, по которым вход может получить значение.
Недостатки использования 'setInterval' в данном случае, похоже, не применимы:
вы можете увидеть этот пример и выбрать, какие события вас интересуют:
<!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>
Ну, лучший способ - покрыть те три базы, которые вы перечислили сами. Простой :onblur, :onkeyup и т.д. не сработает, так что просто объедините их.
KeyUp должен охватывать первые две, и если Javascript модифицирует поле ввода, то я надеюсь, что это ваш собственный javascript, так что просто добавьте обратный вызов в функцию, которая модифицирует его.
.К сожалению, нет ни одного события или набора событий, соответствующих вашим критериям. Клавишное нажатие и копирование/вставка могут быть обработаны событием 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, такое решение, вероятно, не очень хорошо масштабируется, если нужно следить за большим количеством входов. Вы всегда можете настроить 2-й параметр на setInterval()
для более или менее частой проверки.
Этот код 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
....
}
});
});
Я могу опоздать на вечеринку, но не могли бы вы просто использовать событие .change (), которое предоставляет jQuery.
Вы должны уметь делать что-то вроде ...
$(#CONTROLID).change(function(){
do your stuff here ...
});
Вы всегда можете привязать его к списку элементов управления с помощью чего-то вроде ...
var flds = $("input, textarea", window.document);
flds.live('change keyup', function() {
do your code here ...
});
Живое связывание гарантирует, что все элементы, которые существуют на странице сейчас и в будущем обработаны.