Как определить содержимое текстового поля изменилось


Я хочу, чтобы обнаружить, когда содержимое текстового поля изменилось. Я могу использовать метод keyup, но это также будет обнаруживать нажатия клавиш, которые не генерируют буквы, как клавиши со стрелками. Я думал о двух способах сделать это с помощью события keyup:

  1. четко проверьте, является ли код ascii нажатой клавиши буквойbackspacedelete
  2. используйте замыкания, чтобы вспомнить, что был текст в текстовом поле до нажатия клавиши и проверить, имеет ли это измененный.

оба выглядят довольно громоздко.

13 385

13 ответов:

начните наблюдать событие ' input 'вместо'change'.

jQuery('#some_text_box').on('input', function() {
    // do your stuff
});

...что приятно и чисто, но может быть расширено дальше:

jQuery('#some_text_box').on('input propertychange paste', function() {
    // do your stuff
});

используйте событие onchange в HTML / стандартном JavaScript.

в jQuery это изменить() событие. Например:

$('element').change(function() { // do something } );

EDIT

после прочтения некоторых комментариев, что о:

$(function() {
    var content = $('#myContent').val();

    $('#myContent').keyup(function() { 
        if ($('#myContent').val() != content) {
            content = $('#myContent').val();
            alert('Content has been changed');
        }
    });
});

событие ' change 'не работает правильно, но' input ' идеально подходит.

$('#your_textbox').bind('input', function() {
    /* This will be fired every time, when textbox's value changes. */
} );

Как насчет этого:

$("#input").bind("propertychange change keyup paste input", function(){
    // do stuff;
});

> jQuery 1.7

$("#input").on("propertychange change keyup paste input", function(){
    // do stuff;
});

это работает в IE8 / IE9, FF, Chrome

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

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

однако! Это все равно не будет ловить каждое изменение, потому что есть способы редактирования содержимого текстового поля, которые не включают в себя нажатие клавиши. Например, выбрав диапазон текста, затем щелкните правой кнопкой мыши-вырезать. Или тащить его. Или удаление текста из другого приложения в текстовое поле. Или изменить слово с помощью проверки орфографии браузера. Или...

Так что если вы должны обнаружить все изменения, вы должны запросить его. Вы могли бы window.setInterval чтобы проверять поле по его предыдущему значению каждую (скажем) секунду. Вы также можете подключитьonkeyup к той же функции, так что изменяет это are вызванные нажатия клавиш отражаются быстрее.

громоздко? Да. Но это так или просто сделать это обычный HTML onChange, после чего так и не пытайтесь мгновенного обновления.

$(document).on('input','#mytxtBox',function () { 
 console.log($('#mytxtBox').val());
});

вы можете использовать событие 'input' для обнаружения изменения содержимого в текстовом поле. Не используйте "live" для привязки события, поскольку оно устарело в Jquery-1.7, поэтому используйте "on".

Я предполагаю, что вы хотите сделать что-то интерактивное, когда текстовое поле изменяется (т. е. получить некоторые данные через ajax). Я искал эту же функциональность. Я знаю, что использование глобального не является самым надежным или элегантным решением, но это то, с чем я пошел. Вот пример:

var searchValue = $('#Search').val();
$(function () {
    setTimeout(checkSearchChanged, 0.1);
});

function checkSearchChanged() {
    var currentValue = $('#Search').val();
    if ((currentValue) && currentValue != searchValue && currentValue != '') {
        searchValue = $('#Search').val();
        $('#submit').click();
    }
    else {
        setTimeout(checkSearchChanged, 0.1);
    }
}

здесь важно отметить, что я использую setTimeout, а не setInterval, поскольку я не хочу отправлять несколько запросов одновременно. Это гарантирует, что таймер "останавливается", когда форма представляется и "начинается", когда запрос будет завершен. Я делаю это путем вызова checkSearchChanged, когда мой AJAX-вызов завершается. Очевидно, вы можете расширить это, чтобы проверить минимальную длину и т. д.

в моем случае, я использую ASP.Net MVC, чтобы вы могли увидеть, как связать это с MVC Ajax, а также в следующем сообщении:

http://geekswithblogs.net/DougLampe/archive/2010/12/21/simple-interactive-search-with-jquery-and-asp.net-mvc.aspx

Я бы порекомендовал взглянуть на виджет jQuery автозаполнения пользовательского интерфейса. Они обрабатывали большинство случаев там, так как их кодовая база более зрелая, чем большинство из них.

ниже есть ссылка на демо-страницу, так что вы можете проверить его работоспособность. http://jqueryui.com/demos/autocomplete/#default

вы получите максимальную выгоду от чтения источника и посмотреть, как они решили его. Вы можете найти его здесь: https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.autocomplete.js.

В основном они все это делают, они привязываются к input, keydown, keyup, keypress, focus and blur. Тогда у них есть специальная обработка для всех видов ключей, таких как page up, page down, up arrow key and down arrow key. Таймер используется перед получением содержимого текстового поля. Когда пользователь вводит ключ, который не соответствует команде (клавиша вверх, клавиша вниз и т. д.), есть таймер, который исследует содержимое примерно через 300 миллисекунд. Это выглядит так в код:

// switch statement in the 
switch( event.keyCode ) {
            //...
            case keyCode.ENTER:
            case keyCode.NUMPAD_ENTER:
                // when menu is open and has focus
                if ( this.menu.active ) {
                    // #6055 - Opera still allows the keypress to occur
                    // which causes forms to submit
                    suppressKeyPress = true;
                    event.preventDefault();
                    this.menu.select( event );
                }
                break;
            default:
                suppressKeyPressRepeat = true;
                // search timeout should be triggered before the input value is changed
                this._searchTimeout( event );
                break;
            }
// ...
// ...
_searchTimeout: function( event ) {
    clearTimeout( this.searching );
    this.searching = this._delay(function() { // * essentially a warpper for a setTimeout call *
        // only search if the value has changed
        if ( this.term !== this._value() ) { // * _value is a wrapper to get the value *
            this.selectedItem = null;
            this.search( null, event );
        }
    }, this.options.delay );
},

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

таким образом, вы можете использовать виджет или скопировать код в свой собственный виджет, если вы не используете jQuery UI (или в моем случае разрабатываете пользовательский виджет).

Я хотел бы спросить, почему вы пытаетесь определить, когда содержимое текстового поля изменилось в настоящее время?

альтернативой было бы установить таймер (через setIntval?) и сравните последнее сохраненное значение с текущим, а затем сбросьте таймер. Это гарантировало бы улавливание любых изменений, вызванных клавишами, мышью, каким-либо другим устройством ввода, которое вы не рассматривали, или даже JavaScript, изменяющим значение (еще одна возможность, о которой никто не упоминал) из другой части приложение.

вы рассматриваете использование событие изменения ?

$("#myTextBox").change(function() { alert("content changed"); });

использовать textchange событие через настроенную прокладку jQuery для кросс-браузера input совместимость. http://benalpert.com/2013/06/18/a-near-perfect-oninput-shim-for-ie-8-and-9.html (совсем недавно раздвоенный github: https://github.com/pandell/jquery-splendid-textchange/blob/master/jquery.splendid.textchange.js)

это обрабатывает все входные тегов <textarea>content</textarea>, который не всегда работает с changekeyup etc. (!) Только в jQuery on("input propertychange") ручки <textarea> теги последовательно, и выше это прокладка для всех браузеров, которые не понимают input событие.

<!DOCTYPE html>
<html>
<head>
<script class="jsbin" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="https://raw.githubusercontent.com/pandell/jquery-splendid-textchange/master/jquery.splendid.textchange.js"></script>
<meta charset=utf-8 />
<title>splendid textchange test</title>

<script> // this is all you have to do. using splendid.textchange.js

$('textarea').on("textchange",function(){ 
  yourFunctionHere($(this).val());    });  

</script>
</head>
<body>
  <textarea style="height:3em;width:90%"></textarea>
</body>
</html>

JS Bin test

это также обрабатывает вставку, удаление и не дублирует усилия на keyup.

если не используется прокладка, используйте jQuery on("input propertychange") событий.

// works with most recent browsers (use this if not using src="...splendid.textchange.js")

$('textarea').on("input propertychange",function(){ 
  yourFunctionHere($(this).val());    
});  

есть полный рабочий пример здесь.

<html>
<title>jQuery Summing</title>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"> </script>
$(document).ready(function() {
$('.calc').on('input', function() {
var t1 = document.getElementById('txt1');
var t2 = document.getElementById('txt2');
var tot=0;
if (parseInt(t1.value))
tot += parseInt(t1.value);
if (parseInt(t2.value))
tot += parseInt(t2.value);
document.getElementById('txt3').value = tot;
});
});
</script>
</head>
<body>
<input type='text' class='calc' id='txt1'>
<input type='text' class='calc' id='txt2'>
<input type='text' id='txt3' readonly>
</body>
</html>

что-то вроде этого должно работать, главным образом потому, что focus и focusout будет в конечном итоге с двумя отдельными значениями. Я использую data здесь, потому что он хранит значения в элементе, но не касается DOM. Это также простой способ, чтобы сохранить значение, связанное с его элементом. Вы можете так же легко использовать переменную с более высокой областью.

var changed = false;

$('textbox').on('focus', function(e) {
    $(this).data('current-val', $(this).text();
});

$('textbox').on('focusout', function(e) {
    if ($(this).data('current-val') != $(this).text())
        changed = true;
    }
    console.log('Changed Result', changed);
}