Обнаружить все изменения в <input type = "text" > (немедленно) с помощью JQuery

Существует множество способов изменения значения <input type="text">, в том числе:

  • нажатия клавиш
  • копировать/вставить
  • изменено с помощью JavaScript
  • автозаполнение браузером или панелью инструментов

Я хочу, чтобы моя функция JavaScript вызывалась (с текущим значением ввода) в любое время, когда она изменяется. И я хочу, чтобы он сразу вызывался, а не только когда вход теряет фокус.

Я ищу самый чистый и самый надежный способ сделать это во всех браузерах (желательно с помощью jQuery).

Пример использования: на странице Twitter Registration значение поля имени пользователя отображается в URL-адресе " http://twitter/ имя пользователя" ниже.

Ответ 1

К сожалению, я думаю, что setInterval выигрывает приз:

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

Это самое чистое решение, всего в 1 строке кода. Он также является самым надежным, так как вам не нужно беспокоиться обо всех различных событиях/способах, которые input может получить значение.

Недостатки использования 'setInterval', похоже, не применяются в этом случае:

  • Задержка в 100 мс? Для многих приложений 100 мс достаточно быстро.
  • Добавлена ​​нагрузка на браузер? В целом, добавление большого количества setIntervals на вашей странице плохое. Но в этом конкретном случае добавленная загрузка страницы не обнаруживается.
  • Он не масштабируется для многих входов? На большинстве страниц не более нескольких входов, которые вы можете обнюхивать в одном и том же setInterval.

Ответ 2

Этот код 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
       ....
     }
   });
 });

Ответ 3

Приятное решение в режиме реального времени для 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".

Ответ 4

Привязка к событию oninput, похоже, отлично работает в большинстве здравомыслящих браузеров. IE9 также поддерживает его, но реализация ошибочна (событие не запускается при удалении символов).

С помощью jQuery версии 1.7+ метод on полезен для привязки к событию следующим образом:

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

Ответ 5

2017 ответ: входное событие делает именно это для чего-то более нового, чем IE8.

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

Ответ 6

К сожалению, нет событий или событий, соответствующих вашим критериям. Ключи и копирование/вставка могут обрабатываться с событием keyup. Изменения через JS более сложны. Если у вас есть контроль над кодом, который устанавливает текстовое поле, лучше всего изменить его, чтобы либо вызвать вашу функцию напрямую, либо вызвать пользовательское событие в текстовом поле:

// Compare the textbox 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);

Такой активный мониторинг не будет сразу же проверять обновления, но он кажется достаточно быстрым, чтобы не было заметного отставания. Как отметил ДрЛуи в комментариях, это решение, вероятно, не очень хорошо масштабируется, если вам нужно смотреть много материалов. Вы всегда можете настроить 2-й параметр на setInterval(), чтобы проверить более или менее часто.

Ответ 7

Вот несколько другое решение, если вы не представили ни одного из других ответов:

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

Считайте, что вы не можете полагаться на клик и клавиатуру для захвата вставки контекстного меню.

Ответ 8

Я создал образец. Пусть это сработает для вас.

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/

Ответ 9

Добавьте этот код где-нибудь, это сделает трюк.

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() не вызывает change() в jQuery

Ответ 10

На самом деле нам не нужно настраивать циклы для обнаружения изменений 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");

и ofc это доступно только в том случае, если у вас есть полный контроль над изменениями javascript в вашем проекте.

Ответ 11

Хорошо, лучший способ состоит в том, чтобы покрыть те три базы, которые вы указали сами. Простой: onblur,: onkeyup и т.д. Не будут работать для того, что вы хотите, поэтому просто соедините их.

KeyUp должен охватывать первые два, и если Javascript изменяет поле ввода, я уверен, надеюсь, что это ваш собственный javascript, поэтому просто добавьте обратный вызов в функцию, которая его модифицирует.

Ответ 12

Здесь рабочий пример, который я использую для реализации вариации автозаполнения, заполняет селектор (список) 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>");
            }
        }); 
});

Ответ 13

Не можете ли вы использовать элемент <span contenteditable="true" spellcheck="false"> вместо <input type="text">?

<span>contenteditable="true" spellcheck="false" в качестве атрибутов) выделяется <input> главным образом потому, что:

  • Это не стиль, как <input>.
  • У него нет свойства value, но текст отображается как innerText и составляет часть его внутреннего тела.
  • Он многострочный, тогда как <input> нет, хотя вы устанавливаете атрибут multiline="true".

Чтобы выполнить внешний вид, вы можете, конечно, стилизовать его в CSS, а записывая значение innerText, вы можете получить для него событие:

Здесь fiddle.

К сожалению, есть что-то, что на самом деле не работает в IE и Edge, которые я не могу найти.

Ответ 14

вы можете увидеть этот пример и выбрать, какие события вас интересуют:

<!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>

Ответ 15

Возможно, я опаздываю на вечеринку, но не могу ли вы просто использовать событие .change(), которое предоставляет jQuery.

Вы должны иметь возможность сделать что-то вроде...

$(#CONTROLID).change(function(){
    do your stuff here ...
});

Вы всегда можете привязать его к списку элементов управления с чем-то вроде...

var flds = $("input, textarea", window.document);

flds.live('change keyup', function() {
    do your code here ...
});

Связывание в реальном времени гарантирует, что все элементы, которые существуют на странице сейчас и в будущем, обрабатываются.

Ответ 16

Это самый быстрый & чистый способ сделать это:

Я использую JQuery →

$('selector').on('change', function () {
    console.log(this.id+": "+ this.value);
});

Он работает отлично для меня.