admin管理员组

文章数量:1401663

Is it possible with only one bind to either keyup, keypress or keydown to find out that the field value has been changed?

I mean - some key presses don't change the value (like pressing left arrow) and some do (like pressing any letter-button or backspace).

So is it possible to know that key press caused the value change having only one binding?

PS: yes, I realize I could save the value somewhere and pare it in the very begin of event handler, but is there a solution without temporary variables?

Is it possible with only one bind to either keyup, keypress or keydown to find out that the field value has been changed?

I mean - some key presses don't change the value (like pressing left arrow) and some do (like pressing any letter-button or backspace).

So is it possible to know that key press caused the value change having only one binding?

PS: yes, I realize I could save the value somewhere and pare it in the very begin of event handler, but is there a solution without temporary variables?

Share Improve this question edited Mar 29, 2012 at 21:27 zerkms asked Mar 29, 2012 at 21:22 zerkmszerkms 255k73 gold badges447 silver badges547 bronze badges 4
  • Do you want to account for the following situation as well: You press the left arrow, and an event binded to the keypress makes it's own modifications to the textbox. – Chris Laplante Commented Mar 29, 2012 at 21:24
  • @SimpleCoder: not actually. I want something to happen only if keypress caused the real value change. – zerkms Commented Mar 29, 2012 at 21:25
  • you should also consider the fact that you can change the value of an input field without actually pressing a key. You can select text and move it around via drag&drop. You can remove selected text via context menu. You can copy&paste via context menu. etc.. – Kaii Commented Mar 29, 2012 at 21:45
  • @Kaii: exactly. And I only need to care of changes made by keyboard – zerkms Commented Mar 29, 2012 at 21:50
Add a ment  | 

3 Answers 3

Reset to default 4

I don’t think so. I mean, you can map key codes that you assume will be silent, but that map might not be 100% reliable as the input value can change or loose focus depending on how the OS and browser is set up.

Is there a special reason for not detecting change via a variable? It seems like the most reliable thing since this is also exactly what you need to detect:

var input = $('input'),
    val = input.val();
input.keyup(function(e) {
    ​​​​​​​if (val != (val = $(this).val())) {
        console.log('change');
    }
});​

If you don’t want to use stray variables, how about saving it in the data attribute?

$('input').keyup(function(e) {
    ​​​​​​​if ($(this).val() != $(this).data('value')) {
        console.log('change');
    }
    $(this).data('value', $(this).val());
});​

Update based on your ment

You can also use the input event (in modern browsers) to detect change if you don’t care about keys:

$('input').bind('input', function() { 
   console.log('changed');
});

The last option would be to use an interval and keep checking the input field (this might be the most reliable option).

Based on information from MDN's KeyboardEvent section, it looks like that:

  • all keys you are interested in will reliably generate a keypress event each time the key is about to be processed
  • you can tell which key is being pressed (keyCode / key), and also if it has a printable representation or not (if it does then it will alter the value; but keys without printable representation may also alter it)

Going to other sources than MDN yields also this nice resource which has information on how the keyCode property is populated across browsers.

A superior alternative to the above would be the DOM level 3 textInput event, which however also has serious drawbacks:

  1. It is not currently implemented across major browsers
  2. It does not, as far as I can see, apply when text is removed from an input element

I'm quite sure you cannot do this properly without storing the original value somewhere.

Try this if you only want to detect the changes really done by keyboard interaction.

$('#foo').keydown(function (e) {
    this.data = this.value;
});

$('#foo').keyup(function (e) {
    if(this.data != this.value) {
        console.log('changed from "' + this.data + '" to "' + this.value + '"');
    }
});

Note there still is the cornercase when the user holds a key down (lets say: arrow key), then modifies the field content with the mouse, then releases the key.

But this is very unlikely to happen and i guess is acceptable.

本文标签: javascriptFinding out if keypress changed the valueStack Overflow