連続したイベントをキャンセルし、一定時間が過ぎたらイベントを発火させる

寺尾で質問をした。

イベントを遅らせて発火させ、イベントオブジェクトから target 要素を取得したい
もうちょっと自身で精査すればよかったのに・・・自己解決した。
これで文字を入力するたびに処理しなくてもよくなった。

<!DOCTYPE html>
<meta charset="UTF-8">
<title>イベントを遅らせられた</title>

<body>
<input type="text" name="inp"><br />
<input type="text" name="inp"><br />


<script>

/*****************************
  連続するイベントをキャンセルし、一定時間が経過したらイベントを発生させる

  const obj = EventDelay.create (eventType [, target[, delayTime[, useCapture]]]);

******************************/


class EventDelay {

  constructor (type, target, delayTime) {
    this.type      = type;
    this.target    = target;
    this.delayTime = delayTime;

    this.timerId   = null;
    this.event     = null;
    this.disabled  = false;
  }


  dispatch () {
    this.timerOff ();
//× this.target.dispatchEvent (this.event);
    
    if (! this.disabled)
      this.event.target.dispatchEvent (this.event);//イベントのターゲットが肝だった
  }


  timerOff () {
    if (this.timerId)
      clearTimeout (this.timerId);

    this.timerId = null;
  }


  timerOn () {
    if (this.disabled) return;

    let cbFunc = this.dispatch.bind (this);
    this.timerId = setTimeout (cbFunc, this.delayTime);
  }


  handleEvent (event) {
    this.timerOff ();

    if (this.disabled) return;

    if (event.isTrusted) {
      this.event = event;
      event.stopImmediatePropagation ();
      this.timerOn ();
    }
  }


  static create (type, target = document, delayTime = 333, useCapture = false) {
    if (1 > arguments.length || ! type)
      throw new Error ('イベントタイプが不正です');
    
    let obj = new this (type, target, delayTime);
    target.addEventListener (type, obj, useCapture);
    target = null;

    return obj;
  }

}

//-----------------------------------------------

//document に対する inputイベントを 333m/s 遅らせる
EventDelay.create ('input');

//-----------------------------------------------

document.addEventListener ('input', event=> {
  let e = event.target;
  console.log (event, e.value);// value値を取得
}, false);

</script> 

ちょっとした時間があり、全面的に見直した。

<!DOCTYPE html>
<title></title>
<meta charset="utf-8">
<style>
</style>
<body>

<script>

  class DelayTask {

    #id = null; //setTimeout関数の戻り値に使用
 
    constructor (callBackFunc, delayTime) {
      this.callBackFunc = callBackFunc; // func.bind (this)
      this.delayTime = delayTime;
    }

    execute (...args) {
      this.timer = null;
      this.callBackFunc (...args);
    }


    start (...args) {
      let cbFunc = this.execute.bind (this, ...args);
      this.timer = setTimeout (cbFunc, this.delayTime);
      return this;
    }

    stop () {
      this.timer = null;
      return this;
    }

    set timer (id) {
      if (this.#id)
        clearTimeout (this.#id);
      this.#id = id;
    }

    get timer () {
      return this.#id;
    }

    //__________________

    static create (cbFunc, delayTime = 500) {
      if ('function' != typeof cbFunc)
        throw new Error ('関数ではありません');
      return new this (cbFunc, delayTime);
    }
  }

  //_____________________________________________________

  //遅延させてハンドラを呼び出す
  class DelayHandler extends DelayTask {

    constructor (handler, delayTime) {
      super (handler, delayTime);
    }

    handleEvent (event) {
      this.stop ().start (event);
    }

    static create (handler, delayTime = 300) {
      let cbFunc;

      //引数のチェック
      switch (Object.prototype.toString.call (handler)) {
      case '[object Function]' :
        cbFunc = handler;
        break;

      case '[object Object]' :
        if ('handleEvent' in handler) {
          if ('function' === typeof handler.handleEvent)
            cbFunc = handler.handleEvent.bind (handler);
        } //else Error !! 

      default:
        throw new Error ('Not handleEvent');
        break;
      }

      return new this (cbFunc, delayTime);
    }
  }

//_____________________________________________________

function handler (event) {
  console.log(event);
  alert ('クリックされた');
}

document.addEventListener ('click', DelayHandler.create (handler, 1000), false);


</script>