Respostas:
Você precisará usar onkeyup e onchange para isso. O onchange impedirá a colagem do menu de contexto e o onkeyup será acionado para cada pressionamento de tecla.
Veja minha resposta em Como impor maxlength no textArea para um exemplo de código.
onkeyupé um evento terrível para a detecção de entrada. Use oninpute onpropertychange(para suporte do IE).
onchange é acionado quando ocorre um recorte / colagem no menu de contexto.
Estamos em 2012, a era pós-PC chegou e ainda temos que lutar com algo tão básico quanto isso. Isso deve ser muito simples .
Até que esse sonho seja realizado, eis a melhor maneira de fazer isso, em vários navegadores: use uma combinação dos eventos inputeonpropertychange , da seguinte forma:
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
});
}
O inputevento cuida do IE9 +, FF, Chrome, Opera e Safari e onpropertychangecuida do IE8 (também funciona com o IE6 e 7, mas existem alguns bugs).
A vantagem de usar inpute onpropertychangeé que eles não disparam desnecessariamente (como ao pressionar as teclas Ctrlou Shift); portanto, se você deseja executar uma operação relativamente cara quando o conteúdo da área de texto muda, este é o caminho a seguir .
Agora, o IE, como sempre, faz um trabalho sem sentido para apoiar isso: inputnem onpropertychangedispara no IE quando os caracteres são excluídos da área de texto. Portanto, se você precisar lidar com a exclusão de caracteres no IE, use keypress(em vez de usar keyup/ keydown, porque eles são acionados apenas uma vez, mesmo que o usuário pressione e mantenha pressionada uma tecla).
Fonte: http://www.alistapart.com/articles/expanding-text-areas-made-elegant/
EDIT: Parece que até a solução acima não é perfeita, como corretamente apontado nos comentários: a presença da addEventListenerpropriedade na área de texto não implica que você esteja trabalhando com um navegador sensato; Da mesma forma, a presença da attachEventpropriedade não implica IE. Se você deseja que seu código seja realmente hermético, considere mudar isso. Veja o comentário de Tim Down para obter dicas.
addEventListenernão implica suporte para o inputevento ou vice-versa); a detecção de recursos seria melhor. Veja esta postagem do blog para uma discussão sobre isso.
oninputé assim que devemos fazer isso, mas você provavelmente não deveria estar usando addEventListenercomo teste para suporte ao navegador. +1 em qualquer caso.
keypressevento para lidar com esse caso no IE9 (e possivelmente também em versões posteriores).
Não testado no Firefox.
var isIE = /*@cc_on!@*/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>
Sei que essa não é exatamente sua pergunta, mas achei que isso poderia ser útil. Para certas aplicações, é bom que a função de alteração seja acionada nem sempre que uma tecla é pressionada. Isso pode ser alcançado com algo como isto:
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);
}
}();
Isso funciona testando se um evento mais recente foi disparado dentro de um certo período de atraso. Boa sorte!
Eu sei que essa pergunta era específica para JavaScript, no entanto, parece não haver uma maneira boa e limpa de SEMPRE detectar quando uma área de texto é alterada em todos os navegadores atuais. Aprendi que o jquery cuidou disso para nós. Ele até lida com alterações de menu contextual em áreas de texto. A mesma sintaxe é usada independentemente do tipo de entrada.
$('div.lawyerList').on('change','textarea',function(){
// Change occurred so count chars...
});
ou
$('textarea').on('change',function(){
// Change occurred so count chars...
});
bind("input cut paste"...e funciona como um encanto - digitando, recortando e colando usando o teclado ou o menu de contexto; até arraste / solte o texto.
changeevento para textarea.
Você pode ouvir o evento sobre a alteração da área de texto e fazer as alterações conforme desejado. Aqui está um exemplo.
(() => {
const textArea = document.getElementById('my_text_area');
textArea.addEventListener('input', () => {
let textLn = textArea.value.length;
if(textLn >= 100) {
textArea.style.fontSize = '10pt';
}
})
})()
<html>
<textarea id='my_text_area' rows="4" cols="50" style="font-size:40pt">
This text will change font after 100.
</textarea>
</html>
A digitação deve ser suficiente se combinada com o atributo de padrão / validação de entrada HTML5. Portanto, crie um padrão (regex) para validar a entrada e agir de acordo com o status .checkValidity (). Algo como abaixo poderia funcionar. No seu caso, você deseja que uma regex corresponda ao comprimento. Minha solução está em uso / pode ser demo on-line aqui .
<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;
}
});
Código que usei para o IE 11 sem jquery e apenas para uma única área de texto:
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's of your form and textarea objects
<form>.<textarea>.value= <form>.<textarea>.value.substring(0,max);
}
e html:
<TEXTAREA onpropertychange='limit_char(5)' ...
Tente este. É simples e, desde 2016, tenho certeza de que funcionará na maioria dos navegadores.
<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;
}
A melhor coisa que você pode fazer é definir uma função a ser chamada em um determinado período de tempo e essa função para verificar o conteúdo da sua área de texto.
self.setInterval('checkTextAreaValue()', 50);