Как я могу привязать к событию изменения текстовой области в jQuery?

220

Я хочу захватить, если какие-либо изменения произошли с <textarea>. Например, ввод любых символов (удаление, возврат) или щелчок мышью и вставка или вырезание. Есть ли событие jQuery, которое может запускаться для всех этих событий?

Я попытался изменить событие, но он вызывает обратный вызов только после выхода из компонента.

Использование : я хочу включить кнопку, если <textarea>текст содержит какой-либо текст.

Лолли
источник
18
Связывание с ключевыми событиями недостаточно, поскольку текст можно изменить с помощью мыши («вставить» / «вырезать» из контекстного меню или перетащить и отпустить).
Константин Смолянин
Подобный вопрос обсуждается в текстовой области обнаружения изменений .
dma_k

Ответы:

334

Попробуйте это на самом деле:

$('#textareaID').bind('input propertychange', function() {

      $("#yourBtnID").hide();

      if(this.value.length){
        $("#yourBtnID").show();
      }
});

DEMO

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

взрыватель
источник
5
@Senthilnathan: В Chrome и FF для меня не работает, потому что его просто propertychangeнет,input
Blaster
4
Остерегайтесь, поскольку я только что объявил, что ни одно из этих двух событий не запускается в IE9 (не проверял более старые версии IE), когда клавиша возврата назад нажата в текстовой области.
Заппа
26
Эти демки используют <input type="text">, а не<textarea>
Бен Коллинз
5
Измените 'input propertychange' на 'input change', чтобы он работал и в IE9. paulbakaus.com/2012/06/14/propertychange-on-internet-explorer-9
c0D3l0g1c
11
Я вижу, вы использовали <input type = "textarea" cols = "10" rows = "4" /> в DEMO, серьезно?
DrLightman
142

bindустарела. Используйте on:

$("#textarea").on('change keyup paste', function() {
    // your code here
});

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

var oldVal = "";
$("#textarea").on("change keyup paste", function() {
    var currentVal = $(this).val();
    if(currentVal == oldVal) {
        return; //check to prevent multiple simultaneous triggers
    }

    oldVal = currentVal;
    //action to be performed on textarea changed
    alert("changed!");
});

jsFiddle Demo

загвоздка
источник
3
on("change", function() ....часть не работает для меня. Не вызывает ни предупреждений, ни консольных журналов, ничего. Для Keyup работает как шарм, хотя.
Себастьянсо
3
@Sebastialonso: on("change", function() ... будет уволен только тогда , когда текстовое поле теряет фокус . Для этого обратитесь к моему предыдущему вопросу и попробуйте его на этой скрипке - измените текстовую область, затем щелкните за пределами текстовой области, и вы должны увидеть запуск события изменения.
SNag
@ SNag этот код не работает на Chrome 45, но он работает на FF 41
DariusVE
Если вы застряли с использованием jQuery до версии 1.7, то это не относится
Code Jockey
Проголосование за использование на устаревшей функции. Гораздо лучше, чем .bind ()
Дэнни Хардинг
79

Используйте inputсобытие.

var button = $("#buttonId");
$("#textareaID").on('input',function(e){
  if(e.target.value === ''){
    // Textarea has no value
    button.hide();
  } else {
    // Textarea has a value
    button.show();
  }
});
Стальной мозг
источник
Для Internet Explorer для правильной работы требуется 9+ или даже 10+.
Уди
1
Это решение работает как шарм. Прекрасно преодолевает ограничения обработчиков событий change () и keypress (). Спасибо большое за вилки.
Викар
25

На этот вопрос требовался более актуальный ответ с источниками. Вот что на самом деле работает (хотя вы не должны верить мне на слово):

// Storing this jQuery object outside of the event callback 
// prevents jQuery from having to search the DOM for it again
// every time an event is fired.
var $myButton = $("#buttonID")

// input           :: for all modern browsers [1]
// selectionchange :: for IE9 [2]
// propertychange  :: for <IE9 [3]
$('#textareaID').on('input selectionchange propertychange', function() {

  // This is the correct way to enable/disabled a button in jQuery [4]
  $myButton.prop('disabled', this.value.length === 0)

}

1: https://developer.mozilla.org/en-US/docs/Web/Events/input#Browser_compatibility
2: oninput в IE9 не срабатывает, когда мы нажимаем BACKSPACE / DEL / do CUT
3: https: // msdn .microsoft.com / en-us / library / ms536956 (v = vs.85) .aspx
4: http://api.jquery.com/prop/#prop-propertyName-function

НО, для более глобального решения, которое вы можете использовать в своем проекте , я рекомендую использовать плагин textchange jQuery, чтобы получить новое, совместимое с браузером textchangeсобытие. Он был разработан тем же человеком, который реализовал аналогичное onChangeсобытие для ReactJS Facebook, которое они используют почти для всего своего сайта. И я думаю, можно с уверенностью сказать, что если это достаточно надежное решение для Facebook, оно, вероятно, достаточно надежно для вас. :-)

ОБНОВЛЕНИЕ: если вам понадобятся такие функции, как поддержка перетаскивания в Internet Explorer, вы можете вместо этого попробовать pandellнедавно обновленную ветвьjquery-splendid-textchange .

Крис Фриц
источник
Хотя кажется, что «selectionchange» работает только применительно к документу. Активный элемент можно получить с помощью «document.activeElement».
ТФЭ
11

2018, без JQUERY

Вопрос с JQuery, это просто FYI.

JS

let textareaID = document.getElementById('textareaID');
let yourBtnID = document.getElementById('yourBtnID');
textareaID.addEventListener('input', function() {
    yourBtnID.style.display = 'none';
    if (textareaID.value.length) {
        yourBtnID.style.display = 'inline-block';
    }
});

HTML

<textarea id="textareaID"></textarea>
<button id="yourBtnID" style="display: none;">click me</div>
рэп-2-х
источник
4

Вот еще одна (современная), но немного другая версия, чем упомянутые ранее. Протестировано с IE9:

$('#textareaID').on('input change keyup', function () {
  if (this.value.length) {
    // textarea has content
  } else {
    // textarea is empty
  }
});

Для устаревших браузеров вы также можете добавить selectionchangeи propertychange(как упоминалось в других ответах). Но selectionchangeу меня не сработало в IE9. Вот почему я добавил keyup.

kevinweber
источник
2

Попробуйте сделать это с фокусом

$("textarea").focusout(function() {
   alert('textarea focusout');
});
llioor
источник
1

попробуй это ...

$("#txtAreaID").bind("keyup", function(event, ui) {                          

              // Write your code here       
 });
оставайся голодным
источник
7
Связывание с ключевыми событиями недостаточно, поскольку текст можно изменить с помощью мыши («вставить» / «вырезать» из контекстного меню или перетащить и отпустить).
Константин Смольянин
1

.delegate - единственный, кто работает со мной с jQuery JavaScript Library v2.1.1

 $(document).delegate('#textareaID','change', function() {
          console.log("change!");
    });
eeadev
источник
0

После некоторых экспериментов я придумал эту реализацию:

$('.detect-change')
    .on('change cut paste', function(e) {
        console.log("Change detected.");
        contentModified = true;
    })
    .keypress(function(e) {
        if (e.which !== 0 && e.altKey == false && e.ctrlKey == false && e.metaKey == false) {
            console.log("Change detected.");
            contentModified = true;
        }
    });

Обрабатывает изменения для любого вида ввода и выбора, а также текстовые области, игнорируя клавиши со стрелками и такие вещи, как ctrl, cmd, функциональные клавиши и т. Д.

Примечание: я пробовал это только в FF, так как это для дополнения FF.

Rooster242
источник
-11

Попробуй это

 $('textarea').trigger('change');
 $("textarea").bind('cut paste', function(e) { });
Раджеш Тандукар
источник
это не совсем неправильно. На самом деле, если кто-то объединяет $("#textarea").on('change keyup paste', function() {})и $('textarea').trigger('change');может решить проблему, которая мешает pasteработать автоматически!
Лоретопариси