Event when input value is changed by JavaScript?

监听 js 动态 修改 input value 事件

方案1

function customInputSetter(){

  var descriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value");
  var originalSet = descriptor.set;

  // define our own setter
  descriptor.set = function(val) {
    console.log("Value set", this, val);
    originalSet.apply(this,arguments);
  }

  Object.defineProperty(HTMLInputElement.prototype, "value", descriptor);
}

customInputSetter();

方案2
Here is a solution to hook the value property changed for all inputs:

var valueDescriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value");

HTMLInputElement.prototype.addInputChangedByJsListener = function(cb) {
    if(!this.hasOwnProperty("_inputChangedByJSListeners")) {
        this._inputChangedByJSListeners = [];
    }
    this._inputChangedByJSListeners.push(cb);
}

Object.defineProperty(HTMLInputElement.prototype, "value", {
    get: function() {
        return valueDescriptor.get.apply(this, arguments);
    },
    set: function() {
        var self = this;
        valueDescriptor.set.apply(self, arguments);
        if(this.hasOwnProperty("_inputChangedByJSListeners")){
            this._inputChangedByJSListeners.forEach(function(cb) {
                cb.apply(self);
            })
        }
    }
});

//Usage example:
document.getElementById("myInput").addInputChangedByJsListener(function() {
    console.log("Input changed to \"" + this.value + "\"");
});

方案3

 
/**
 * [changeValueListener 监听 js 修改 input 和 textarea 的 value。]
 * @param  {[HTMLElement]}   element  [具有 value 属性的 html 元素,如 input 和 textarea。]
 * @param  {Function} callback [回调,this 为 element,参数为当前值。]
 * @return {[HTMLElement]}            [element]
 */
function changeValueListener(element, callback) {
    if (!Array.isArray(element.callbacks)) {
        element.callbacks = [];
        var valueDes = Object.getOwnPropertyDescriptor(element.constructor.prototype, "value");
        Object.defineProperty(element, 'value', {
            set: function(v) {
                // console.log('set', v, this, arguments);
                element.callbacks.forEach(function(callback) {
                    callback.call(this, v);
                });
                valueDes.set.apply(this, arguments);
            },
            get: function() {
                // console.log('get', this, arguments);
                return valueDes.get.apply(this, arguments);
            }
        });
    }
    element.callbacks.push(callback);
    return element;
}

// 调用
var input = document.getElementById('foo');
changeValueListener(input, function(v) {
    console.log('a callback', this, v);
});
// 支持绑定多个回调
changeValueListener(input, function(v) {
    console.log('b callback', this, v);
});
posted @ 2020-11-27 14:06  China Soft  阅读(153)  评论(0编辑  收藏  举报