¿Cómo puedo vincularme al evento de cambio de un área de texto en jQuery?

219

Quiero capturar si sucedió algún cambio <textarea>. Como escribir cualquier carácter (eliminar, retroceder) o hacer clic con el mouse y pegar o cortar. ¿Hay un evento jQuery que pueda desencadenar todos esos eventos?

Intenté cambiar el evento, pero activa la devolución de llamada solo después de eliminar el componente.

Uso : Quiero habilitar un botón si a <textarea>contiene algún texto.

Paleta
fuente
18
La vinculación a eventos clave no es suficiente porque el texto se puede cambiar con el mouse ("pegar" / "cortar" desde el menú contextual o arrastrar y soltar).
Konstantin Smolyanin
Una pregunta similar se discute en la detección de cambio de área de Textarea .
dma_k

Respuestas:

333

Prueba esto en realidad:

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

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

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

MANIFESTACIÓN

Eso funciona para cualquier cambio que realice, escribir, cortar, pegar.

Desintegrador
fuente
55
@Senthilnathan: No funciona en Chrome y FF también para mí porque simplemente no propertychangeexiste tambiéninput
Blaster
44
Tenga cuidado, ya que acabo de descubrir que ninguno de estos dos eventos se dispara en IE9 (no he verificado versiones anteriores de IE) cuando se presiona la tecla de retroceso en un área de texto.
Zappa
26
Estas demostraciones están usando <input type="text">, no<textarea>
Ben Collins
55
Cambie 'input propertychange' a 'input change' para que funcione también en IE9. paulbakaus.com/2012/06/14/propertychange-on-internet-explorer-9
c0D3l0g1c
11
Veo que usaste <input type = "textarea" cols = "10" rows = "4" /> en la DEMO, ¿en serio?
DrLightman
142

bindes obsoleto. Uso on:

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

Nota: El código anterior se disparará varias veces, una por cada tipo de disparador coincidente. Para manejar eso, haga algo como esto:

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

Engancharse
fuente
3
La on("change", function() ....parte no me funciona. No activa ninguna alerta, ni registros de consola, nada. Sin embargo, para keyup funciona como un encanto.
Sebastialonso
3
@Sebastialonso: El on("change", function() ... es solamente activa cuando el área de texto pierde el foco . Consulte mi pregunta anterior para esto, y pruébelo en este violín : cambie el área de texto, luego haga clic fuera del área de texto, y debería ver cómo se activa el evento de cambio.
SNag
@SNag ese código no funciona en Chrome 45, pero funciona en FF 41
DariusVE
Sin embargo, si está atascado con jQuery antes de la versión 1.7, entonces esto no se aplica
Code Jockey,
upvoting para su uso en funciones no obsoletas. Mucho mejor que .bind ()
Danny Harding
79

Usa un 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();
  }
});
Cerebro de acero
fuente
Para Internet Explorer, esto requiere 9+, o incluso 10+ para funcionar correctamente.
Udi
1
Esta solución funciona a las mil maravillas. Supera perfectamente las limitaciones de los controladores de eventos change () y keypress (). Gracias un montón de tenedores.
Vickar
25

Esta pregunta necesitaba una respuesta más actualizada, con fuentes. Esto es lo que realmente funciona (aunque no tiene que tomar mi palabra):

// 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 en IE9 no se activa cuando pulsamos BACKSPACE / DEL / do CUT
3: https: // msdn .microsoft.com / es-us / library / ms536956 (v = vs.85) .aspx
4: http://api.jquery.com/prop/#prop-propertyName-function

PERO, para obtener una solución más global que pueda usar en todo su proyecto , le recomiendo usar el complemento jQuery de cambio de texto para obtener un nuevo textchangeevento compatible con varios navegadores . Fue desarrollado por la misma persona que implementó el onChangeevento equivalente para ReactJS de Facebook, que utilizan para casi todo su sitio web. Y creo que es seguro decir que si es una solución lo suficientemente robusta para Facebook, probablemente sea lo suficientemente sólida para usted. :-)

ACTUALIZACIÓN: Si necesita funciones como la compatibilidad con arrastrar y soltar en Internet Explorer, puede consultar la pandellbifurcación actualizada más recientemente dejquery-splendid-textchange .

Chris Fritz
fuente
Aunque parece que "selectionchange" funciona solo cuando se aplica al documento. El elemento activo se puede obtener con "document.activeElement".
tfE
11

2018, sin JQUERY

La pregunta es con JQuery, es solo para su información.

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
fuente
4

Aquí hay otra versión (moderna) pero ligeramente diferente a las mencionadas anteriormente. Probado con IE9:

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

Para los navegadores obsoletos también puede agregar selectionchangey propertychange(como se menciona en otras respuestas). Pero selectionchangeno funcionó para mí en IE9. Por eso agregué keyup.

kevinweber
fuente
2

Intenta hacerlo con foco

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

prueba esto ...

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

              // Write your code here       
 });
quedarse con hambre
fuente
77
La vinculación a eventos clave no es suficiente porque el texto se puede cambiar con el mouse ("pegar" / "cortar" desde el menú contextual o arrastrar y soltar).
Konstantin Smolyanin
1

.delegate es el único que está trabajando para mí con la versión 2.1.1 de jQuery JavaScript Library

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

Después de experimentar un poco, se me ocurrió esta implementación:

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

Maneja los cambios en cualquier tipo de entrada y selecciona, así como las áreas de texto, ignorando las teclas de flecha y cosas como ctrl, cmd, teclas de función, etc.

Nota: solo he intentado esto en FF ya que es para un complemento FF.

Gallo242
fuente
-11

Prueba esto

 $('textarea').trigger('change');
 $("textarea").bind('cut paste', function(e) { });
Rajesh Tandukar
fuente
Esto no está completamente mal. De hecho, si uno combina $("#textarea").on('change keyup paste', function() {})y $('textarea').trigger('change');puede abordar el problema que impide pastetrabajar automáticamente.
loretoparisi