Domanda

Voglio rilevare ogni volta che il contenuto di una casella di testo è cambiato. Posso utilizzare il metodo keyup, ma che sarà anche rilevare sequenze di tasti che non generano le lettere, come i tasti freccia. Ho pensato a due metodi per farlo utilizzando l'evento KeyUp:

  1. Verificare esplicitamente se il codice ASCII del tasto premuto è una lettera \ backspace \ eliminare
  2. chiusure per ricordare quello che era il testo nella casella di testo prima che il tratto chiave e verificare se questo è cambiato.

Entrambi guardano un pò ingombrante.

È stato utile?

Soluzione

Inizia osservando evento 'input' invece di 'cambiamento'.

jQuery('#some_text_box').on('input', function() {
    // do your stuff
});

... che è bello e pulito, ma può essere esteso ulteriormente a:

jQuery('#some_text_box').on('input propertychange paste', function() {
    // do your stuff
});

Altri suggerimenti

Utilizzare l'evento onchange in HTML / JavaScript standard.

In jQuery che è il () evento. Ad esempio:

$('element').change(function() { // do something } );

Modifica

Dopo aver letto alcuni commenti, che dire:

$(function() {
    var content = $('#myContent').val();

    $('#myContent').keyup(function() { 
        if ($('#myContent').val() != content) {
            content = $('#myContent').val();
            alert('Content has been changed');
        }
    });
});

L'evento 'cambiamento' non funziona correttamente, ma il 'input' è perfetto.

$('#your_textbox').bind('input', function() {
    /* This will be fired every time, when textbox's value changes. */
} );

Che ne dite di questo:

$("#input").bind("propertychange change keyup paste input", function(){
    // do stuff;
});

> jQuery 1.7

$("#input").on("propertychange change keyup paste input", function(){
    // do stuff;
});

Questo funziona in IE8 / IE9, FF, Chrome

  

Utilizzare chiusure di ricordare quello che era il testo nella casella di controllo prima che il tratto chiave e verificare se questo è cambiato.

Sì. Non è necessario usare chiusure necessariamente, ma è necessario ricordare il vecchio valore e confrontarlo con il nuovo.

Tuttavia! Questo ancora non prenderà ogni cambiamento, perché c'è un modi di modifica dei contenuti di testo che non comportano alcuna pressione di un tasto. Per esempio selezionando un intervallo di testo, quindi fare clic destro taglio. O trascinandolo. O far cadere il testo da un'altra applicazione nella casella di testo. O cambiare una parola tramite controllo ortografico del browser. Oppure ...

Quindi, se si deve rilevare ogni cambiamento, si deve eseguire il polling per esso. Si potrebbe window.setInterval per controllare il campo contro il suo valore precedente ogni (diciamo) secondo. Si potrebbe anche onkeyup filo alla stessa funzione modo che le modifiche che sono causata da immissioni sono riflesse veloce.

ingombrante? Sì. Ma è che o semplicemente farlo nel normale modo onchange HTML e non cercare di instant-aggiornamento.

$(document).on('input','#mytxtBox',function () { 
 console.log($('#mytxtBox').val());
});

È possibile utilizzare evento 'ingresso' per rilevare la modifica del contenuto nella casella di testo. Non utilizzare 'live' per legare l'evento come si è deprecato in jQuery-1.7, quindi fare uso di 'on'.

Presumo che si sta cercando di fare qualcosa di interattivo quando cambia la casella di testo (cioè recuperare alcuni dati tramite la tecnologia AJAX). Ero alla ricerca di questa stessa funzionalità. So che usando un globale non è la soluzione più robusta o elegante, ma questo è quello che ho passato con. Ecco un esempio:

var searchValue = $('#Search').val();
$(function () {
    setTimeout(checkSearchChanged, 0.1);
});

function checkSearchChanged() {
    var currentValue = $('#Search').val();
    if ((currentValue) && currentValue != searchValue && currentValue != '') {
        searchValue = $('#Search').val();
        $('#submit').click();
    }
    else {
        setTimeout(checkSearchChanged, 0.1);
    }
}

Una cosa fondamentale da notare qui è che sto usando setTimeout e non setInterval dato che non voglio inviare più richieste allo stesso tempo. Questo assicura che il timer "stop" quando il modulo viene inviato e "inizia" quando la richiesta è completa. Faccio questo chiamando checkSearchChanged quando la mia chiamata AJAX completa. Ovviamente si potrebbe espandere questa per verificare la lunghezza minima, etc.

Nel mio caso, io sto usando ASP.Net MVC modo da poter vedere come legare questa con MVC Ajax e nel seguente post:

http://geekswithblogs.net/DougLampe/archive/2010/12/21/simple-interactive-search-with-jquery-and-asp.net-mvc.aspx

Consiglio di prendere uno sguardo al widget di jQuery UI autocomplete. Hanno gestito la maggior parte dei casi in quanto la loro base di codice è più maturo rispetto alla maggior parte quelli là fuori.

Di seguito è riportato un link ad una pagina di prova in modo da poter verificare il funzionamento. http://jqueryui.com/demos/autocomplete/#default

Si otterrà il massimo beneficio dalla lettura del sorgente e vedere come hanno risolto esso. Lo si può trovare qui: https: // GitHub .com / jquery / jquery-ui / blob / master / ui / jquery.ui.autocomplete.js .

In pratica lo fanno tutti, si legano a input, keydown, keyup, keypress, focus and blur. Poi hanno una gestione speciale per tutti i tipi di tasti come page up, page down, up arrow key and down arrow key. Un timer viene utilizzato prima di ottenere il contenuto della casella di testo. Quando un utente preme un tasto che non corrisponde ad un comando (tasto di aumento, giù chiave e così via) c'è un timer che esploratori il contenuto dopo circa 300 millisecondi. Ecco come si presenta nel codice:

// switch statement in the 
switch( event.keyCode ) {
            //...
            case keyCode.ENTER:
            case keyCode.NUMPAD_ENTER:
                // when menu is open and has focus
                if ( this.menu.active ) {
                    // #6055 - Opera still allows the keypress to occur
                    // which causes forms to submit
                    suppressKeyPress = true;
                    event.preventDefault();
                    this.menu.select( event );
                }
                break;
            default:
                suppressKeyPressRepeat = true;
                // search timeout should be triggered before the input value is changed
                this._searchTimeout( event );
                break;
            }
// ...
// ...
_searchTimeout: function( event ) {
    clearTimeout( this.searching );
    this.searching = this._delay(function() { // * essentially a warpper for a setTimeout call *
        // only search if the value has changed
        if ( this.term !== this._value() ) { // * _value is a wrapper to get the value *
            this.selectedItem = null;
            this.search( null, event );
        }
    }, this.options.delay );
},

Il motivo di utilizzare un timer è in modo che l'interfaccia utente ha la possibilità di essere aggiornato. Quando Javascript è in esecuzione l'interfaccia utente non può essere aggiornato, quindi la chiamata alla funzione di ritardo. Questo funziona bene per altre situazioni come mantenere focus sul testo (utilizzato da tale codice).

Quindi, è possibile utilizzare il widget o se non si utilizza jQuery UI copiare il codice nel tuo widget (o nel mio caso lo sviluppo di un widget personalizzato).

Mi piacerebbe chiedere perché si sta cercando di rilevare quando il contenuto della casella di testo è cambiato in tempo reale

Un'alternativa sarebbe quella di impostare un timer (tramite setIntval?) E confrontare il valore salvato l'ultima volta a quella attuale e quindi reimpostare un timer. Ciò garantirebbe la cattura di ogni cambiamento, a causa di tasti, il mouse, qualche altro dispositivo di input ha non prendere in considerazione, o cambiare addirittura JavaScript del valore (un altro possiblity nessuno ha menzionato) da una parte diversa della app.

si fa a considerare l'utilizzo di evento ?

$("#myTextBox").change(function() { alert("content changed"); });

Utilizzare l'evento textchange tramite personalizzato spessore jQuery per la compatibilità input cross-browser. http: / /benalpert.com/2013/06/18/a-near-perfect-oninput-shim-for-ie-8-and-9.html (github più recente biforcuta: https://github.com/pandell/jquery-splendid-textchange/blob/master /jquery.splendid.textchange.js )

Questo gestisce tutti i tag di ingresso compreso <textarea>content</textarea>, che non sempre funziona con change keyup ecc (!) Solo jQuery on("input propertychange") gestisce tag <textarea> modo coerente, e quanto sopra è uno spessore per tutti i browser che non capiscono evento input.

<!DOCTYPE html>
<html>
<head>
<script class="jsbin" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="https://raw.githubusercontent.com/pandell/jquery-splendid-textchange/master/jquery.splendid.textchange.js"></script>
<meta charset=utf-8 />
<title>splendid textchange test</title>

<script> // this is all you have to do. using splendid.textchange.js

$('textarea').on("textchange",function(){ 
  yourFunctionHere($(this).val());    });  

</script>
</head>
<body>
  <textarea style="height:3em;width:90%"></textarea>
</body>
</html>

prova JS Bin

Questo gestisce anche incolla, cancella, e non duplica sforzo da keyup.

Se non si utilizza uno spessore, utilizzare gli eventi on("input propertychange") jQuery.

// works with most recent browsers (use this if not using src="...splendid.textchange.js")

$('textarea').on("input propertychange",function(){ 
  yourFunctionHere($(this).val());    
});  

C'è un completo esempio di lavoro qui .

<html>
<title>jQuery Summing</title>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"> </script>
$(document).ready(function() {
$('.calc').on('input', function() {
var t1 = document.getElementById('txt1');
var t2 = document.getElementById('txt2');
var tot=0;
if (parseInt(t1.value))
tot += parseInt(t1.value);
if (parseInt(t2.value))
tot += parseInt(t2.value);
document.getElementById('txt3').value = tot;
});
});
</script>
</head>
<body>
<input type='text' class='calc' id='txt1'>
<input type='text' class='calc' id='txt2'>
<input type='text' id='txt3' readonly>
</body>
</html>

Qualcosa del genere dovrebbe funzionare, soprattutto perché focus e focusout finirebbe con due valori distinti. Sto usando data qui perché memorizza valori nella elemento, ma non tocchi il DOM. E 'anche un modo semplice per memorizzare il valore connessi al suo elemento. Si potrebbe altrettanto facilmente utilizzare una variabile più alto con ambito.

var changed = false;

$('textbox').on('focus', function(e) {
    $(this).data('current-val', $(this).text();
});

$('textbox').on('focusout', function(e) {
    if ($(this).data('current-val') != $(this).text())
        changed = true;
    }
    console.log('Changed Result', changed);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top