Como vincular ao evento change de uma área de texto no jQuery?

219

Quero capturar se alguma alteração aconteceu <textarea>. Como digitar qualquer caractere (excluir, retroceder) ou clicar e colar ou recortar. Existe um evento jQuery que pode ser acionado para todos esses eventos?

Tentei alterar o evento, mas ele aciona o retorno de chamada somente depois de separar o componente.

Uso : desejo ativar um botão se a <textarea>contiver algum texto.

Lolly
fonte
18
A ligação a eventos importantes não é suficiente porque o texto pode ser alterado com o mouse ("cole" / "recorte" no menu de contexto ou arraste e solte).
Konstantin Smolyanin 18/03/2013
Pergunta semelhante é discutida na detecção de mudança de área de texto .
dma_k

Respostas:

333

Tente realmente:

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

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

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

DEMO

Isso funciona para qualquer alteração que você fizer, digitar, recortar e colar.

Blaster
fonte
5
@Senthilnathan: Não funciona no Chrome e FF bem para mim, porque não é apenas propertychangehá tambéminput
Blaster
4
Cuidado, pois acabei de descobrir que nenhum desses dois eventos é acionado no IE9 (não verificou versões mais antigas do IE) quando a tecla backspace é pressionada em uma área de texto.
Zappa
26
Estas demonstrações estão usando <input type="text">, não<textarea>
Ben Collins
5
Altere 'input propertychange' para 'input change' para que também funcione no IE9. paulbakaus.com/2012/06/14/propertychange-on-internet-explorer-9
c0D3l0g1c
11
Vejo que você usou <input type = "textarea" cols = "10" linhas = "4" /> na DEMO, sério?
DrLightman
142

bindestá obsoleto. Use on:

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

Nota: O código acima será acionado várias vezes, uma vez para cada tipo de gatilho correspondente. Para lidar com isso, faça algo assim:

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

SNag
fonte
3
a on("change", function() ....parte não está funcionando para mim. Não aciona nenhum alerta, nem logs do console, nada. Para keyup funciona como um encanto, no entanto.
Sebastialonso
3
@Sebastialonso: on("change", function() ... é acionado quando a área de texto perde o foco . Consulte minha pergunta anterior e experimente-a neste assunto - altere a área de texto, clique fora da área de texto e você verá o evento de alteração sendo disparado.
Senão
@SNag esse código não está funcionando no Chrome 45, mas está funcionando no FF 41
DariusVE 9/15
Se você está preso usando jQuery anteriores à versão 1.7, no entanto, em seguida, isto não se aplica
Código Jockey
voto positivo para uso em função não obsoleta. Muito melhor do que .bind ()
Danny Harding
79

Use um inputevento.

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();
  }
});
Cérebro de aço
fonte
Para o Internet Explorer, isso requer 9 ou 10 ou mais para funcionar corretamente.
Udi
1
Esta solução funciona como um encanto. Supera perfeitamente os limites dos manipuladores de eventos change () e keypress (). Graças uma tonelada garfos.
Vickar
25

Esta pergunta precisava de uma resposta mais atualizada, com fontes. Isto é o que realmente funciona (embora você não precise acreditar na minha palavra):

// 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 no IE9 não dispara quando pressionamos BACKSPACE / DEL / do CUT
3: https: // msdn .microsoft.com / pt-br / library / ms536956 (v = vs.85) .aspx
4: http://api.jquery.com/prop/#prop-propertyName-function

MAS, para uma solução mais global que você possa usar em todo o projeto , recomendo usar o plugin jQuery de troca de texto para obter um novo textchangeevento compatível com vários navegadores . Foi desenvolvido pela mesma pessoa que implementou o onChangeevento equivalente ao ReactJS do Facebook, usado por quase todo o site. E acho seguro dizer que, se é uma solução robusta o suficiente para o Facebook, provavelmente é robusta o suficiente para você. :-)

ATUALIZAÇÃO: Se você precisar de recursos como suporte a arrastar e soltar no Internet Explorer, poderá conferir a pandellbifurcação atualizada mais recentementejquery-splendid-textchange .

Chris Fritz
fonte
Embora pareça que a "seleção de alteração" funcione apenas quando aplicada ao documento. O elemento ativo pode ser obtido com "document.activeElement".
tfE 27/12/16
11

2018, sem JQUERY

A questão é com JQuery, é apenas para sua informação.

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>
rap-2-h
fonte
4

Aqui está outra versão (moderna), mas um pouco diferente das mencionadas anteriormente. Testado com o IE9:

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

Para navegadores desatualizados, você também pode adicionar selectionchangee propertychange(como mencionado em outras respostas). Mas selectionchangenão funcionou para mim no IE9. Por isso eu adicionei keyup.

kevinweber
fonte
2

Tente fazer isso com foco

$("textarea").focusout(function() {
   alert('textarea focusout');
});
llioor
fonte
1

tente isso ...

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

              // Write your code here       
 });
permaneça faminto
fonte
7
A ligação a eventos importantes não é suficiente porque o texto pode ser alterado com o mouse ("cole" / "recorte" no menu de contexto ou arraste e solte).
Konstantin Smolyanin
1

.delegate é o único que está trabalhando para mim com a jQuery JavaScript Library v2.1.1

 $(document).delegate('#textareaID','change', function() {
          console.log("change!");
    });
eeadev
fonte
0

Depois de algumas experiências, criei esta implementação:

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

Lida com alterações em qualquer tipo de entrada e seleciona, além de áreas de texto, ignorando teclas de seta e coisas como ctrl, cmd, teclas de função, etc.

Nota: Eu só tentei isso no FF, pois é para um complemento do FF.

Rooster242
fonte
-11

Tente isto

 $('textarea').trigger('change');
 $("textarea").bind('cut paste', function(e) { });
Rajesh Tandukar
fonte
isso não está completamente errado. De fato, se alguém combinar $("#textarea").on('change keyup paste', function() {})e $('textarea').trigger('change');puder resolver o problema que impede pastetrabalhar automaticamente!
loretoparisi 25/01/19