7

We all know that use the val() will not trigger the change event, so we also use .trigger('change') behind the val().

But the problem is that someone write the val() did't with trigger() and it's a external file that I can't edit it.

So, how can I detect value change through some code same like below:

$('.elem').on('change', function(){
   // do something
});
Harry Yu
  • 323
  • 1
  • 3
  • 11
  • 1
    Why not add your own event listener for the element and then listen for the .trigger() event from there? – Aweary Dec 15 '14 at 04:07
  • 1
    You might want to see the `watch` function : http://stackoverflow.com/questions/1029241/javascript-object-watch-for-all-browsers – naota Dec 15 '14 at 04:17
  • @naota I make a demo after learn `watch`: http://jsfiddle.net/yujiangshui/yfo7rrn8/. It works, but the watcher code must above the `val()` code and I set a `setInterval` to monitor the value change.It's a way, but I think it's not a elegant way. Or I'm using in a wrong way? – Harry Yu Dec 15 '14 at 06:06
  • @Jiangshui OK, I saw your code on the jsfiddle. I guess this article might help you: http://james.padolsey.com/javascript/monitoring-dom-properties/ – naota Dec 15 '14 at 08:15

5 Answers5

1

My suggestion is to override jquery's val()

var originalValFn = jQuery.fn.val;

jQuery.fn.val = function() {
    this.trigger('change');
    originalValFn.apply( this, arguments );
}

jsfiddle: http://jsfiddle.net/2L7hohjz/js

BMH
  • 4,280
  • 1
  • 18
  • 18
  • You should probably check that arguments.length is greater than zero before triggering the event, otherwise simply reading a value with obj.val() will also trigger it. – dssjoblom Aug 13 '21 at 07:16
1
var originalValFn = jQuery.fn.val;

function getErrorObject(){
    try { throw Error('') } catch(err) { return err; }
}

jQuery.fn.val = function() {
    if ($(this).hasClass( "element" )) {
        var err = getErrorObject();
        var caller_line = err.stack.split("\n")[4];
        var index = caller_line.indexOf("at ");
        var clean = caller_line.slice(index+2, caller_line.length);

        console.log(clean);
        console.log(arguments);
    }
    originalValFn.apply( this, arguments );
};
  • 2
    You should provide more context to your answer, just posting code isn't enough to explain why your answer is the correct one. – Adam Mar 29 '17 at 18:43
0

Try:

setTimeout(function() {
     if (currentValue != previousValue)
     {
        // do something
     }
}, 500);

Thank you,

Jedi
  • 87
  • 2
0

I commonly use the solution from this post to get around problems like this one:

hidden input change event

watchField('.elem', function(){
    //do some stuff here
});

function watchField(selector, callback) {
   var input = $(selector);
   var oldvalue = input.val();
   setInterval(function(){
      if (input.val()!=oldvalue){
          oldvalue = input.val();
          callback();
      }
   }, 100);
}
Community
  • 1
  • 1
Josh Whitlow
  • 481
  • 6
  • 25
-1

Try:

$('.elem').on('keyUp', function(){
   // do something
});

or

$('.elem').on('lostFocus', function(){
   // do something
});

Thank you,

Jedi
  • 87
  • 2
  • Use val() to change value, it will not trigger `change` event, and also not trigger `keyup` or `lostfocus` event, it not work. – Harry Yu Dec 15 '14 at 05:23