自定义 KeyboardEvent 不冒泡

Custom KeyboardEvent does not bubble

出于某种原因,我的自定义 KeyboardEvent 没有冒泡。 我负责处理holding key:

document.addEventListener('DOMContentLoaded', function () {
  var isPressed = false;
  var startTimeStamp;

  document.addEventListener('keydown', function (e) {    
    if (!isPressed) {
      startTimeStamp = e.timeStamp;
      isPressed = true;
    }
  });

  document.addEventListener('keyup', function (e) {
    isPressed = false;

    var eventDuration = e.timeStamp - startTimeStamp;

    var _e = new KeyboardEvent('keyheld', {
      bubbles: true,
      cancelBubble: false,
      cancelable: true,
      char: e.char,
      charCode: e.charCode,
      key: e.key,
      keyCode: e.keyCode,
      which: e.which,
      shiftKey: e.shiftKey,
      ctrlKey: e.ctrlKey,
      altKey: e.altKey,
      metaKey: e.metaKey
    });

    Object.defineProperty(_e, 'detail', {
        value: {
            duration: eventDuration
        },
        enumerable: true
    });

    document.dispatchEvent(_e);
  });
});

然后我可以使用附加到 document 的侦听器来处理 keyheld 事件。尽管如此,附加到任何东西(下面是 body)的侦听器根本不会触发:

document.addEventListener('DOMContentLoaded', function () {
    document.body.addEventListener('keyheld', function (e) {
      console.log('KEY HELD: ', e.detail.duration, e);
    });
});

上面的代码不起作用,更奇怪的是,即使 true 作为 addEventListener() 的第三个参数提供,它应该在捕获而不是冒泡时触发侦听器。

这里可能有什么问题?

当您调用 document.dispatchEvent(event) 时,事件 is dispatched with its target set to document, which is the top-level node in the DOM hierarchy, as can be seen in an illustration here

事件通常会 bubble 到目标元素的父元素,但是当目标是 document 时,没有父元素 (document.parentNode === null)。出于同样的原因,尝试在 body 上注册捕获侦听器不起作用。

您可能想分派到原始事件的目标:e.target.dispatchEvent(_e)