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

338

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

  • Проверяем, если код ascii нажатой клавиши - это буква \backspace\delete
  • Используйте блокировки, чтобы запомнить, что было в текстовом поле перед нажатием клавиши, и проверить, не изменилось ли это.

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

  • 7
    Да, ловить ключ для этого плохо. Вы можете вставить вещи без каких-либо нажатий клавиш вообще.
  • 2
    есть ли шанс, что вы можете опубликовать свое окончательное решение? Мне тоже нужно решить эту проблему :)
Показать ещё 4 комментария
Теги:
textbox
keypress

13 ответов

592
Лучший ответ

Начните наблюдать "входное" событие вместо "change".

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

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

jQuery('#some_text_box').on('input propertychange paste', function() {
    // do your stuff
});
  • 12
    'live' устарела. так что используйте «on» stackoverflow.com/a/15111970/1724777
  • 21
    Единственным недостатком «ввода» является то, что он не совместим с IE <9.
Показать ещё 10 комментариев
63

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

В jQuery, который является событием change(). Например:

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

ИЗМЕНИТЬ

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

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

    $('#myContent').keyup(function() { 
        if ($('#myContent').val() != content) {
            content = $('#myContent').val();
            alert('Content has been changed');
        }
    });
});
  • 3
    Да, это похоже на то, что я предложил в варианте № 2 в моем вопросе. Я предпочитаю замыкания, так как использование global сделает эту функцию работающей только для одного текстового поля. Во всяком случае, кажется странным JQuery не имеет более простой способ сделать это.
  • 1
    Это действительно странно, но я сомневаюсь, что есть лучший способ сделать это. Вы можете использовать setInterval, а затем проверять, менялось ли содержимое каждые 0,1 секунды, и затем что-то делать. Это также будет включать пасты мыши и так далее. Но это не звучит слишком элегантно.
Показать ещё 1 комментарий
42

Событие "change" работает неправильно, но "вход" идеален.

$('#your_textbox').bind('input', function() {
    /* This will be fired every time, when textbox value changes. */
} );
  • 7
    Это отлично подходит для моей ситуации, хотя рекомендуется использовать .on начиная с 1.7 (а не .bind ).
  • 6
    -1 к сожалению это не кросс-браузерное решение
Показать ещё 4 комментария
33

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

< jQuery 1.7

$("#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

  • 1
    Проблема с этим ответом заключается в том, что он срабатывает после размытия текстового поля, даже если значение не изменилось. Виновником является «изменение».
  • 0
    Вы используете Chrome? Кажется, это ошибка в Chrome, а не событие изменения jQuery bugs.jquery.com/ticket/9335
21

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

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

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

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

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

  • 14
    Некоторый исходный код был бы хорош ...
  • 1
    Вот что я придумал gist.github.com/1622014
Показать ещё 1 комментарий
13
$(document).on('input','#mytxtBox',function () { 
 console.log($('#mytxtBox').val());
});

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

  • 1
    Кажется, это не работает на Backspace ..
  • 0
    @Flores Вы уверены ... Это должно работать ...
Показать ещё 2 комментария
5

Я предполагаю, что вы хотите сделать что-то интерактивное при изменении текстового поля (например, получить некоторые данные через 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

4

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

Ниже приведена ссылка на демонстрационную страницу, чтобы вы могли проверить ее работоспособность. 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 (или, в моем случае, разрабатываете собственный виджет).

2

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

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

  • 0
    Моя ситуация (которая привела меня к этому вопросу) заключается в том, что мне нужно показать кнопку «Обновить корзину» при изменении количества в текстовом поле. пользователь понятия не имеет, что ему нужно потерять фокус, и в противном случае он может не увидеть кнопку.
  • 0
    Извините, я не уверен, что это отвечает на вопрос «почему бы не проверить различия в расписании». Просто проверяйте достаточно часто (каждую 1/4 секунды), и пользователь не почувствует никакой разницы.
1

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

$("#myTextBox").change(function() { alert("content changed"); });
  • 5
    AFAIK, он срабатывает только тогда, когда фокус элемента потерян. Кто-то, кто знаком с замыканиями, вероятно, знает об этом. :)
  • 0
    да, этого не произойдет - событие изменения вызывается только тогда, когда текстовое поле теряет фокус. Я хочу обработать изменение сразу после нажатия клавиши.
0

Что-то вроде этого должно работать, главным образом потому, что 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);
}
0

Используйте событие 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>, который не всегда работает с change keyup и т.д. (!) Только 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

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

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

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню