Comment puis-je me lier à l'événement change d'une zone de texte dans jQuery?

219

Je veux capturer si des changements sont survenus <textarea>. Comme taper des caractères (suppression, retour arrière) ou cliquer et coller ou couper avec la souris. Y a-t-il un événement jQuery qui peut se déclencher pour tous ces événements?

J'ai essayé de changer d'événement, mais il ne déclenche le rappel qu'après tabulation du composant.

Utilisation : Je souhaite activer un bouton si a <textarea>contient du texte.

Fric
la source
18
La liaison aux événements clés ne suffit pas car le texte peut être modifié par la souris ("coller" / "couper" dans le menu contextuel ou glisser-déposer).
Konstantin Smolyanin
Une question similaire est discutée dans Textarea onchange detection .
dma_k

Réponses:

333

Essayez ceci en fait:

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

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

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

DEMO

Cela fonctionne pour toutes les modifications que vous apportez, en tapant, en coupant, en collant.

Blaster
la source
5
@Senthilnathan: Pas de travail dans Chrome et FF aussi bien pour moi car ce n'est tout simplement pas le propertychangecas aussiinput
Blaster
4
Attention, je viens de découvrir qu'aucun de ces deux événements ne se déclenche dans IE9 (je n'ai pas vérifié les anciennes versions d'IE) lorsque la touche de retour arrière est enfoncée dans une zone de texte.
Zappa
26
Ces démos utilisent <input type="text">, pas<textarea>
Ben Collins
5
Remplacez «input propertychange» par «input change» pour qu'il fonctionne également dans IE9. paulbakaus.com/2012/06/14/propertychange-on-internet-explorer-9
c0D3l0g1c
11
Je vois que vous avez utilisé <input type = "textarea" cols = "10" rows = "4" /> dans la DEMO, sérieusement?
DrLightman
142

bindest obsolète. Utilisation on:

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

Remarque: Le code ci-dessus se déclenchera plusieurs fois, une fois pour chaque type de déclencheur correspondant. Pour gérer cela, faites quelque chose comme ceci:

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

Accroc
la source
3
la on("change", function() ....partie ne fonctionne pas pour moi. Ne déclenche aucune alerte, ni journaux de console, quoi que ce soit. Pour les touches, cependant, cela fonctionne comme un charme.
Sebastialonso
3
@Sebastialonso: le on("change", function() ... n'est déclenché que lorsque la zone de texte perd le focus . Référez-vous à ma question précédente pour cela, et essayez-la sur ce violon - changez la zone de texte, puis cliquez en dehors de la zone de texte, et vous devriez voir le changement d'événement se déclencher.
SNag
@SNag ce code ne fonctionne pas sur Chrome 45, mais il fonctionne sur FF 41
DariusVE
Si vous êtes bloqué avec jQuery avant la version 1.7, cela ne s'applique pas
Code Jockey
voter pour une utilisation sur une fonction non obsolète. Beaucoup mieux que .bind ()
Danny Harding
79

Utilisez un inputévénement.

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();
  }
});
Cerveau en acier
la source
Pour Internet Explorer, cela nécessite 9+, voire 10+ pour fonctionner correctement.
Udi
1
Cette solution fonctionne comme un charme. Surmonte parfaitement les limites des gestionnaires d'événements change () et keypress (). Merci une tonne de fourchettes.
Vickar
25

Cette question avait besoin d'une réponse plus à jour, avec des sources. C'est ce qui fonctionne réellement (bien que vous n'ayez pas à me croire sur parole):

// 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 dans IE9 ne se déclenche pas lorsque nous frappons 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

MAIS, pour une solution plus globale que vous pouvez utiliser tout au long de votre projet , je recommande d'utiliser le plugin jcery textchange pour obtenir un nouvel textchangeévénement compatible avec tous les navigateurs . Il a été développé par la même personne qui a mis en œuvre l'équivalentonChange événement pour ReactJS de Facebook, qu'ils utilisent pour presque tout leur site Web. Et je pense qu'il est sûr de dire que si c'est une solution suffisamment robuste pour Facebook, elle est probablement assez robuste pour vous. :-)

MISE À JOUR: Si vous avez besoin de fonctionnalités telles que la prise en charge du glisser-déposer dans Internet Explorer, vous souhaiterez peut-être consulter pandellla dernière version mise à jour de fork dejquery-splendid-textchange .

Chris Fritz
la source
Bien qu'il semble que "selectionchange" ne fonctionne que lorsqu'il est appliqué au document. L'élément actif a pu être obtenu avec "document.activeElement".
tfE
11

2018, sans JQUERY

La question est avec JQuery, c'est juste 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>
rap-2-h
la source
4

Voici une autre version (moderne) mais légèrement différente de celles mentionnées précédemment. Testé avec IE9:

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

Pour les navigateurs obsolètes, vous pouvez également ajouter selectionchangeet propertychange(comme mentionné dans d'autres réponses). Mais selectionchangen'a pas fonctionné pour moi dans IE9. C'est pourquoi j'ai ajouté keyup.

Kevinweber
la source
2

Essayez de le faire avec focusout

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

essaye ça ...

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

              // Write your code here       
 });
rester affamé
la source
7
La liaison aux événements clés ne suffit pas car le texte peut être modifié par la souris ("coller" / "couper" dans le menu contextuel ou glisser-déposer).
Konstantin Smolyanin
1

.delegate est le seul qui fonctionne pour moi avec jQuery JavaScript Library v2.1.1

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

Après quelques expérimentations, j'ai trouvé cette implémentation:

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

Gère les modifications de tout type d'entrée et sélectionne ainsi que les zones de texte en ignorant les touches fléchées et des choses comme ctrl, cmd, touches de fonction, etc.

Remarque: je n'ai essayé cela que dans FF car c'est pour un add-on FF.

Rooster242
la source
-11

Essaye ça

 $('textarea').trigger('change');
 $("textarea").bind('cut paste', function(e) { });
Rajesh Tandukar
la source
ce n'est pas complètement faux. En fait, si l'on combine $("#textarea").on('change keyup paste', function() {})et $('textarea').trigger('change');peut résoudre le problème qui empêche pastede travailler automatiquement!
loretoparisi