Cody
Cody

Reputation: 2482

Is there a good cross-browser way to detect changes to an <input> yet?

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?

Upvotes: 2

Views: 2107

Answers (4)

Alex
Alex

Reputation: 12433

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);
    };
};

Upvotes: 1

Jani Hyyti&#228;inen
Jani Hyyti&#228;inen

Reputation: 5407

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>

Upvotes: -1

RandomUs1r
RandomUs1r

Reputation: 4190

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.

Upvotes: -1

Kevin B
Kevin B

Reputation: 95022

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.

Upvotes: 1

Related Questions