Як виявити вміст текстового поля змінився


417

Я хочу виявити, коли зміст вмісту текстового поля змінювався. Я можу використовувати метод клавіатури, але це також виявить натискання клавіш, які не генерують літери, як-от клавіші зі стрілками. Я подумав два способи зробити це за допомогою події клавіатури:

  1. Перевірте explictly, чи є кодом ascii натиснутої клавіші літера \ backspace \ delete
  2. Використовуйте закриття, щоб запам’ятати, яким був текст у текстовому вікні перед натисканням клавіші, і перевірте, чи змінилося це.

Обидва виглядають дещо громіздкими.


7
Так, ловити клавіатуру для цього погано. Ви можете вставити речі без будь-яких натискань клавіш.
витрачений

2
будь-який шанс ви можете опублікувати своє остаточне рішення? Мені теж потрібно вирішити цю проблему :)
Метт Дотсон

1
або .keyup()подія ... Більше інформації тут: stackoverflow.com/questions/3003879/…
Victor S

1
Див. $ ("# Деякий вхід"). ChangePolling () ; для обгортки, яка перевіряє поточне значення та спрацьовує, .change()чи воно змінилося.
Джоел Пурра

Ви повинні перевірити це занадто stackoverflow.com/a/23266812/3160597
azerafati

Відповіді:


714

Почніть спостерігати за подією "введення" замість "зміни".

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

... що є приємним і чистим, але може бути продовжено до:

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

12
"живе" застаріло. тому використовувати «на» stackoverflow.com/a/15111970/1724777
NavaRajan

21
Єдине падіння 'input' - це те, що він не сумісний з IE <9.
Сом

5
input - подія html5, яка підтримується не у всіх браузерах. developer.mozilla.org/en-US/docs/Web/API/window.oninput
commonpike

18
Ви також можете охопити більше підстав, використовуючи: .on ('введення властивостей
змінити

23
Єдине падіння IE <9 - це те, що ніхто не використовує його!
sohaiby

67

Використовуйте подію зміни в HTML / стандартному JavaScript.

У jQuery це подія change () . Наприклад:

$('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');
        }
    });
});

3
Так, це схоже на те, що я запропонував у варіанті №2 у своєму питанні. Я віддаю перевагу закриттю, оскільки використання глобальної функції змусить цю функцію працювати лише для одного текстового поля. У будь-якому випадку, здається, у дивного jquery немає більш простого способу зробити це.
olamundo

1
Це дійсно дивно, але я сумніваюся, що є кращий спосіб зробити це. Ви можете використовувати setInterval, а потім перевіряти, чи змінено вміст кожні 0,1 секунди, а потім щось робити. Сюди також будуть входити пасти для миші тощо. Але це не дуже елегантно.
Уелід Амджад

4
Ще можливо, що зміст можна змінювати без натискання клавіші, наприклад, вставляючи мишу. Якщо ви переймаєтесь цим, теоретично ви могли б також ловити події миші, але це налаштування ще гірше. З іншого боку, якщо ви готові ігнорувати зміни, керовані мишею, це зробиться.
Адам Беллер

45

Подія "зміни" працює неправильно, але "введення" ідеально.

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

7
Це ідеально підходить для моєї ситуації, хоча використання .onрекомендується рекомендувати від 1.7 далі (а не .bind).
Нік

8
ОП не вказала необхідність перехресної сумісності браузера. @schwarzkopfb забезпечив рішення. Немає підстав для голосування, тому що у вас є представник.
Девід Схід

3
@David він також не вказав, який браузер
ozz

9
@ jmo21 Я думаю, що ми можемо припустити, що для веб-розробки, коли браузер не є конкретним, рішення повинно бути багатофункціональним. Норма підтримує всі браузери.
Кріс

3
@Chris "Норма підтримує всі браузери" - лише якщо ви садист. Немає вагомих причин уникати корисності HTML5 для 2% глобальних користувачів на IE 8/9. caniuse.com/#feat=input-event
Ярін

39

Як щодо цього:

<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
Проблема, з якою я маю цю відповідь, це те, що вона спрацьовує, коли ви розмиєте текстове поле, навіть якщо значення не змінилося. Винуватець - «зміна».
Джастін

Використовуєте Chrome? Здається, це помилка з хромом, а не подія змінити jQuery bugs.jquery.com/ticket/9335
Сом

працює, але має незначну помилку, якщо ви робите console.logзначення поля, яке воно записує двічі, коли ви вводите символ.
Самуель М.

21

Використовуйте закриття, щоб запам’ятати, яким був текст у прапорець перед натисканням клавіші, і перевірте, чи змінилося це.

Так. Вам не доведеться використовувати закриття обов'язково, але вам потрібно буде запам'ятати старе значення і порівняти його з новим.

Однак! Це все ще не сприймає кожної зміни, оскільки існують способи редагування вмісту текстового поля, які не передбачають жодного натискання клавіші. Наприклад, вибір діапазону тексту, а потім клацання правою кнопкою миші. Або перетягування. Або викидання тексту з іншої програми в текстове поле. Або змінити слово за допомогою перевірки орфографії браузера. Або ...

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

Громіздкий? Так. Але це те, або просто зробіть це звичайним способом обміну HTML і не намагайтеся миттєво оновлюватись.


1
У наші дні inputподія HTML5 є життєздатною та працює в поточних версіях усіх основних браузерів.
Тім Даун

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

Ви можете використовувати подію "введення" для виявлення зміни вмісту в текстовому полі. Не використовуйте "live" для прив'язки події, оскільки вона застаріла в Jquery-1.7, тому використовуйте "on".


@NavaRajan Просто перевірив його знову в IE9. дійсно не працює на задній простір.
Флорес

Я хочу НЕ використовувати .live, але проблема, яка у мене виникає, полягає в тому, що я якось пішов "назад у майбутнє" і на проект mvc3, в якому керівник команди хоче дотримуватися "поза коробкою", так що не використовується лише EF 4.0, але jquery 1.5.1 використовується THUS .on () не було в 1.5.1, оскільки він був доданий у версії jquery 1.7 api.jquery.com/on
Tom Stickel

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 (або в моєму випадку розробляєте користувацький віджет).


2

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

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


моя ситуація (що призвело до цього питання) полягає в тому, що мені потрібно показати кнопку "Оновити кошик", коли кількість в текстовому полі зміниться. користувач не має уявлення, що їм потрібно втрачати фокус, інакше може не бачити кнопку.
Simon_Weaver

Вибачте, я не впевнений, що це відповідає на питання "чому б не перевірити наявність відмінностей за графіком". Просто перевіряйте досить часто (кожні 1/4 секунди), і користувач не знатиме різниці.
DVK

1

Чи вважаєте ви використовувати подію зміни ?

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

5
AFAIK, він спрацьовує лише тоді, коли втрачається фокус елемента. Хтось, хто знайомий із закриттями, напевно, знає про це. :)
simon

так, це не буде робити - подія зміни викликається лише тоді, коли текстове поле втрачає фокус. Я хочу впоратися зі зміною відразу після натискання клавіші.
olamundo

1

Використовуйте textchangeподію за допомогою спеціалізованого jQuery shim для 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

Це також обробляє вставлення, видалення та не дублює зусилля під час клавіші.

Якщо не використовується shim, використовуйте on("input propertychange")події jQuery .

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

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

Цей Код виявляє, коли користувач змінює вміст текстового поля та змінює код Javascript.

var $myText = jQuery("#textbox");

$myText.data("value", $myText.val());

setInterval(function() {
    var data = $myText.data("value"),
    val = $myText.val();

    if (data !== val) {
        console.log("changed");
        $myText.data("value", val);
    }
}, 100);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.