時間を遅らせてコールバック関数を起動する

時間を遅らせてコールバック関数を起動する

class DelayCBFunc {
  constructor (cbfunc, time = 500 /*ms*/) {
    this.cbfunc = cbfunc;
    this.time = time;
    this.tmid = null;
    this.disabled = false;
  }
  
  restart (...args) { 
    this.stop ();
    this.tmid = setTimeout (this.cbfunc.bind(this,...args), this.time);
  }
  
  stop () {
    if (this.tmid)
      this.tmid = clearTimeout (this.tmid);
  }
}

//--
function delayAlert (e) {
  alert (e.value + 'でした');
}

const DA = new DelayCBFunc (delayAlert, 1000);
const TG = document.querySelector ('input[type="serach"]');

function handle (event) {
  DA.restart (event.target);
}

TG.addEventListener ('input', handle, false);//1秒間に入力がないとアラートする

change イベントを遅らせて発火させる。(input イベントを監視する)

// input イベントを監視して、変更があったら change イベントを発火させる
// コールバックを指定すると change イベント直前に実行できる
class delayChangeEvent {
  constructor (target, delayTime, cbFunc) {

    this.target = target;
    this.delay  = delayTime; //遅延時間(ms)
    this.cbFunc = cbFunc; //その時に実行する関数
    this.disabled = false; //この値を true にすると実行されなくなる
    this.timeId   = null; //setTimeout で使用する
    this.value    = target.value;
    
    // input event を監視する
    target.addEventListener ('input', this, false);
  }
  
  
  //イベントハンドラ
  handleEvent (event) {
    if (this.disabled) return;

    switch (event.type) {
    case 'input' : //input event を監視する
      if (this.timerId)
        clearTimeout (this.timerId);//タイマーを解除

      this.timerId = setTimeout (this.execute.bind (this), this.delay);//タイマー設定
      break;
    }
  }
  

  //change イベントを発火させる
  execute () {
    if (this.disabled) return;

    this.timerId = null;
    if (this.value !== this.target.value) {
      let
        e = this.target,
        event = e.ownerDocument.createEvent ('HTMLEvents');
      event.initEvent ('change', true, true);

      //change イベントの前に コールバックを実行する
      if ('function' === typeof this.cbFunc)
        this.cbFunc (e);

      this.target.dispatchEvent (event);
    }
  }

  //
  static create (target, delayTime = 300, cbFunc = null) {
    if (! target)
      throw new Error ('要素がありません');
    return new this (target, delayTime, cbFunc);
  }
}