Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom KeyboardEvent does not bubble

For some reason, my custom KeyboardEvent does not bubble. I attend to handle 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);
  });
});

And then I can handle keyheld event with a listener attached to document. Nonetheless, a listener attached to anything (below it is body) else does not fire at all:

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

The code above does not work, what even stranger, even with true supplied as the third argument of addEventListener() which should fire a listener when capturing rather than bubbling.

What may be wrong here?

like image 206
Damian Czapiewski Avatar asked Mar 31 '26 09:03

Damian Czapiewski


1 Answers

When you call document.dispatchEvent(event), the 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.

The event would normally bubble to the parents of the target element, but when the target is document, there are no parents (document.parentNode === null). Trying to register a capturing listener on the body doesn't work for the same reason.

You probably wanted to dispatch to the target of the original event: e.target.dispatchEvent(_e).

like image 74
Nickolay Avatar answered Apr 02 '26 22:04

Nickolay



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!