2

First off, I know this has been asked before. I'm asking again in the hopes that more recent versions of common libraries like jQuery have solved this. This may be wishful thinking, I know...

Having said that, is there a way to detect all changes (keypress, paste, autocorrect) to an <input> yet? I was using $("#myElement").bind('input propertychange', function (e) {...}); until IE9 came along and broke it (it doesn't fire on backspace/cut/delete).

There are three options that I'm aware of, all of which have drawbacks:

  1. Bind to even more events (keyup, paste, etc.) and use setTimeout to ignore duplicates.
  2. Bind to specific events based on browser detection.
  3. Bind to even more events, track the old value with jQuery.data(), and compare against it before firing the handler (as in this answer).

If there's not a "better way" yet, which of the above do you prefer, and why?

Community
  • 1
  • 1
Cody
  • 2,467
  • 2
  • 21
  • 30

4 Answers4

1

If you only support modern browsers, Yes there is a way to do it cross-browser using only a single event: input

$(myelement).on('input',function(){
    console.log(this.value);
});

If you wish to continue supporting old browsers, you have to continue using workarounds for them because the older versions of the browsers aren't going to be fixed.

I prefer to pair keydown with input because keydown triggers around the same time that the input event would be triggered.

Kevin B
  • 94,570
  • 16
  • 163
  • 180
  • "only support modern browsers" - Oh, how I wish that were the case ;) Until a couple days ago, IE9 was the latest version for Windows 7, and it's broken there :( – Cody Feb 28 '13 at 21:52
  • Well, it is a little sarcastic i guess, The fact is, if you need to support a browser that doesn't handle something correctly, you have to use a workaround for it to work. You know that, i'm not sure why you even asked this question. You already know the answer to it. I know it sucks to have to do these workarounds for IE, but that's just how it is. Just be happy IE6 is about dead. – Kevin B Feb 28 '13 at 21:54
  • 1
    I asked because a new version of jQuery has been released since the last time I've dealt with this issue, and I want to see if it has any new tricks I didn't know about yet. Minimizing workarounds for different browsers is one of the major benefits of using something like jQuery, so I maintain that this is a pretty reasonable question. – Cody Mar 01 '13 at 00:03
1

As a fallback for browsers that don't support oninput, you can use both onkeyup and oninput events on the field, but debounce the event handler to prevent multiple execution:

$('input').on('keyup input', debounce(function() {
  // do something
  console.log('input'):
}, 500));

var debounce = function(func, wait, immediate) {
    var timeout;
    return function () {
        var context = this, args = arguments;
        var later = function () {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
};
Alex
  • 12,205
  • 7
  • 42
  • 52
-1

You can try the keypress event. I however, use the blur event.

A little bit of philosophy on this for you: I find that text boxes that alter my text in any way shape or form as I'm typing counter intuitive and annoying.

Of course for something like, let's say a 3 field SSN, you want to keep checking the length to shoot them over to the next field, but it's .blur() for everything else.

Marcel Korpel
  • 21,536
  • 6
  • 60
  • 80
RandomUs1r
  • 4,010
  • 1
  • 24
  • 44
  • keypress has the same issue as input in IE9. keyup works though. – Cody Feb 28 '13 at 21:50
  • read: http://stackoverflow.com/questions/492865/jquery-keypress-event-not-firing . It seems that for IE keydown works, but not keypress? A bit frustrating to deal with, but have you tried that? Or any of the other solutions in that thread? – RandomUs1r Feb 28 '13 at 22:02
-1

Try this:

<input type="text" onchange="$(this).trigger('change');">

If it works, you could conditionally use .attr('onchange', '...') for buggy browsers to avoid cluttering your markup with hacks.

<script>
    <!--[if lte IE 9]>
        $('input[type=text]').attr('onchange', '$(this).trigger(\'change\')');
    <![endif]-->
</script>
Jani Hyytiäinen
  • 5,293
  • 36
  • 45