Обнаружение обмена текстовой областью

Как обнаружить событие изменения в textarea с помощью javascript?
Я пытаюсь определить, сколько оставшихся символов доступно при вводе.

Я попытался использовать событие onchange, но, похоже, это только удар, когда фокус отсутствует.

Ответ 1

Для этого вам нужно использовать onkeyup и onchange. Onchange предотвратит вставку контекстного меню, и onkeyup будет срабатывать для каждого нажатия клавиши.

Посмотрите мой ответ на Как наложить maxlength на textArea для образца кода.

Ответ 2

В 2012 году, эпоха пост-ПК здесь, и нам все еще нужно бороться с чем-то основным, как это. Это должно быть очень просто.

До тех пор, пока этот сон не будет выполнен, лучший способ сделать это, кросс-браузер: использовать комбинацию input и onpropertychange события, например:

var area = container.querySelector('textarea');
if (area.addEventListener) {
  area.addEventListener('input', function() {
    // event handling code for sane browsers
  }, false);
} else if (area.attachEvent) {
  area.attachEvent('onpropertychange', function() {
    // IE-specific event handling code
  });
}

Событие input заботится о IE9 +, FF, Chrome, Opera и Safari и onpropertychange заботится о IE8 (он также работает с IE6 и 7, но есть некоторые ошибки).

Преимущество использования input и onpropertychange заключается в том, что они не запускаются без необходимости (например, при нажатии клавиш Ctrl или Shift); поэтому , если вы хотите выполнить относительно дорогостоящую операцию при изменении содержимого textarea, это путь.

Теперь IE, как всегда, выполняет половинную задачу поддержки этого: ни input, ни onpropertychange не запускается в IE, когда символы удаляются из текстового поля. Поэтому, если вам нужно обрабатывать удаление символов в IE, используйте keypress (в отличие от использования keyup/keydown, потому что они срабатывают только один раз, даже если пользователь нажимает и удерживает клавишу нажатой).

Источник: http://www.alistapart.com/articles/expanding-text-areas-made-elegant/

EDIT: Кажется, что даже указанное выше решение не является совершенным, как справедливо указано в комментариях: наличие свойства addEventListener в текстовом поле не означает, что вы работаете с разумный браузер; аналогично наличие свойства attachEvent не означает IE. Если вы хотите, чтобы ваш код был действительно воздушным, вам следует подумать об этом. См. комментарий Tim Down для указателей.

Ответ 3

  • Для Google-Chrome достаточно будет oninput (протестировано в Windows 7 с версией 22.0.1229.94 м).
  • Для IE 9 oninput поймает все, кроме разрезанных через контекстное меню и backspace.
  • Для IE 8 onpropertychange требуется для вставки в дополнение к oninput.
  • Для IE 9 + 8 для включения backspace требуется onkeyup.
  • Для IE 9 + 8 onmousemove - единственный способ, которым я обнаружил, что вырезать через contextmenu

Не тестировалось в Firefox.

    var isIE = /*@[email protected]*/false; // Note: This line breaks closure compiler...

    function SuperDuperFunction() {
        // DoSomething
    }


    function SuperDuperFunctionBecauseMicrosoftMakesIEsuckIntentionally() {
        if(isIE) // For Chrome, oninput works as expected
            SuperDuperFunction();
    }

<textarea id="taSource"
          class="taSplitted"
          rows="4"
          cols="50"
          oninput="SuperDuperFunction();"
          onpropertychange="SuperDuperFunctionBecauseMicrosoftMakesIEsuckIntentionally();"
          onmousemove="SuperDuperFunctionBecauseMicrosoftMakesIEsuckIntentionally();"
          onkeyup="SuperDuperFunctionBecauseMicrosoftMakesIEsuckIntentionally();">
Test
</textarea>

Ответ 4

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

var text = document.createElement('textarea');
text.rows = 10;
text.cols = 40;
document.body.appendChild(text);

text.onkeyup = function(){
var callcount = 0;
    var action = function(){
        alert('changed');
    }
    var delayAction = function(action, time){
        var expectcallcount = callcount;
        var delay = function(){
            if(callcount == expectcallcount){
                action();
            }
        }
        setTimeout(delay, time);
    }
    return function(eventtrigger){
        ++callcount;
        delayAction(action, 1200);
    }
}();

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

Ответ 6

Я знаю, что этот вопрос был специфичен для JavaScript, однако, похоже, нет хорошего и чистого способа ВСЕГДА обнаружить, когда текстовая область изменяется во всех текущих браузерах. Я узнал, что jquery позаботился об этом для нас. Он даже обрабатывает контекстные изменения меню в текстовых областях. Тот же синтаксис используется независимо от типа ввода.

    $('div.lawyerList').on('change','textarea',function(){
      // Change occurred so count chars...
    });

или

    $('textarea').on('change',function(){
      // Change occurred so count chars...
    });

Ответ 8

Код, который я использовал для IE 11 без jquery и только для одного текстового поля:

JavaScript:

// Impede que o comentário tenha mais de num_max caracteres
var internalChange= 0; // important, prevent reenter
function limit_char(max)
{ 
    if (internalChange == 1)
    {
        internalChange= 0;
        return;
    }
    internalChange= 1;
    // <form> and <textarea> are the ID of your form and textarea objects
    <form>.<textarea>.value= <form>.<textarea>.value.substring(0,max);
}

и html:

<TEXTAREA onpropertychange='limit_char(5)' ...

Ответ 9

Ключ должен быть достаточным, если он сопряжен с атрибутом валидации/шаблона ввода HTML5. Итак, создайте шаблон (регулярное выражение) для проверки ввода и действуйте на статус .checkValidity(). Что-то вроде ниже могло работать. В вашем случае вам нужно, чтобы регулярное выражение соответствовало длине. Мое решение находится в использовании/демо-онлайн-режиме здесь.

<input type="text" pattern="[a-zA-Z]+" id="my-input">

var myInput = document.getElementById = "my-input";

myInput.addEventListener("keyup", function(){
  if(!this.checkValidity() || !this.value){
    submitButton.disabled = true;
  } else {
    submitButton.disabled = false;
  }
});

Ответ 10

Попробуйте это. Это просто, и с 2016 года я уверен, что он будет работать в большинстве браузеров.

<textarea id="text" cols="50" rows="5" onkeyup="check()" maxlength="15"></textarea> 
<div><span id="spn"></span> characters left</div>

function check(){
    var string = document.getElementById("url").value
    var left = 15 - string.length;
    document.getElementById("spn").innerHTML = left;
}

Ответ 11

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

self.setInterval('checkTextAreaValue()', 50);